javascript - 如何模拟在我正在测试的函数内部调用的函数?

标签 javascript node.js unit-testing mongoose jestjs

我有一个注册函数,可以将我的用户保存到 Mongoose 数据库中。测试时,我不希望用户实际保存到数据库,所以我想重写 mongoose 保存方法。

我的注册方法是这样的:

async register({firstName, lastName, email, password}){
    try {
        const salt = bcrypt.genSaltSync(10);
        const hash = bcrypt.hashSync(password, salt);

        return await new UserModel({
            firstName,
            lastName,
            email,
            hash
        }).save()

    }catch (err) {
        console.log(`Unable to register new user: ${err}`)
        throw 'Unable to register new user'
    }
}

所以我想测试一下这个方法。我已经编写了测试,但我不知道如何将模拟函数传递到我的 register() 函数

import UserConnector from './user'
import sinon from 'sinon'
import mongoose from 'mongoose'
import UserModel from '../../models/user'

describe("User connector", () => {

    it("should register user", () => {

        const expectedUser = {
            firstName: "adsfja",
            lastName: "adsfja",
            email: "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="90f1f4e3f6faf1d0f1fce3f4f1bef3fffd" rel="noreferrer noopener nofollow">[email protected]</a>",
            password: "password123"
        }

        var myStub = sinon.stub(UserModel.prototype, 'save').withArgs(expectedUser) // <--- How can I pass this into my userConnector.register() method so that the stub is called instead of the real thing

        const user = new UserConnector().register(expectedUser)

        expect(user).toEqual({
            firstName: "adsfja",
            lastName: "adsfja",
            email: "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="0b6a6f786d616a4b6a67786f6a25686466" rel="noreferrer noopener nofollow">[email protected]</a>"
        })

    })
})

如何告诉我的 register() 方法使用 stub 函数而不是调用实际的 mongoose DB?

最佳答案

根据 documentation ,实现这一点的方法是使用 callsFake

参见下面的示例

import UserConnector from './user'
import sinon from 'sinon'
import mongoose from 'mongoose'
import UserModel from '../../models/user'

describe("User connector", () => {

    it("should register user", async () => {

        const expectedUser = {
            firstName: "adsfja",
            lastName: "adsfja",
            email: "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f0919483969a91b0919c839491de939f9d" rel="noreferrer noopener nofollow">[email protected]</a>",
            password: "password123"
        }

        var myStub = sinon
          .stub(UserModel.prototype, 'save')
          .callsFake(() => Promise.resolve(expectedUser))

        const userConnector = new UserConnector();
        // since register is used as async, we should expect it to return a promise
        const user = await userConnector.register(expectedUser)

        expect(user).toEqual({
            firstName: "adsfja",
            lastName: "adsfja",
            email: "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6f0e0b1c09050e2f0e031c0b0e410c0002" rel="noreferrer noopener nofollow">[email protected]</a>"
        })
        myStub.restore() // don't forget to restore stubbed function

    })
})

希望这有帮助

关于javascript - 如何模拟在我正在测试的函数内部调用的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51801027/

相关文章:

javascript - 尝试将 Braintree 嵌套回调转换为 NodeJS 异步/等待语法

javascript - 无法启动 Node 应用程序配置文件

java - Android 单元测试内容解析器类

javascript - 二维字符串数组创建

javascript - 使用 Firebase Firestore 为每个在 Javascript 中动态创建的行分配一个文档 ID

javascript - MongooseJS - 限制子文档中的文档数量

c# - 用于生成对象初始化代码的调试器可视化器

java - Eclipse中粗体蓝色字体的含义

javascript - 我如何在特定时间段后将 css 规则添加到 div,设置延迟,然后再添加一个 css 规则,使用 jquery?

javascript - 将 CSV 文件转换为 JSON 字典?