首页 > 解决方案 > 模拟使用 sequelize-auto 包创建的自动生成的模型函数

问题描述

我已经使用 sequelize-auto 包创建了我的模型并在我的控制器中使用了它们

const sequelize = require('../database/db');
var models = require("../models/init-models").initModels(sequelize);

var User = models.User;

const controllerMethod = async (req,res,next) => {
    //calls User.findAll() and returns the results
}

我在我的控制器方法之一中调用了 User 模型的 findAll 函数

我想使用 Jest 测试我的控制器方法,并想模拟 findAll 函数以返回一个空对象。我已经在测试文件中导入了我的模型并模拟了 findAll 函数,如下所示,

//inside test case
            models.User.findAll = jest.fn().mockImplementation(() => {
                return {}
            });
            const spy = jest.spyOn(models.User, "findAll")
            await controllerMethod(req, res,next);

我的问题是当我运行测试用例时,它在控制器内部运行实际的 findAll() 函数而不是模拟的 findAll()
即 findAll() 返回实际数据而不是 {}

任何帮助将不胜感激
在此先感谢

标签: node.jsjestjssequelize.jssequelize-auto

解决方案


欢迎来到堆栈溢出。我认为您的代码的问题是对工作方式的一些混淆spyOn。请参阅此处的文档,具体如下:

Note: By default, jest.spyOn also calls the spied method. This is different behavior from most other test libraries. If you want to overwrite the original function, you can use jest.spyOn(object, methodName).mockImplementation(() => customImplementation) or object[methodName] = jest.fn(() => customImplementation);

这告诉您的是spyOn实际调用原始方法,而不是模拟实现。

我这样做的方式(并假设您不需要断言如何findAll调用)根本不使用spyOn,而是创建一个models从返回的虚拟对象initModels,其中包含您的虚拟findAll方法。类似于以下内容:

const mockModels = {
        User: {
            findAll: jest.fn(() => {})
        }
    };
    // And then in your test - be careful as jest.mock is "hoisted" so you need to make sure mockModels has already been declared and assigned

test('blah', () => {
    jest.mock("../models/init-models", () => ({
        initModels: jest.fn(() => mockModels,
    });
    await controllerMethod(req, res, next) // ...etc

推荐阅读