You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jest提取mock函数实现灵活mock Sequelize findAll返回值失效问题

问题根因

你的代码有三个明显问题导致mock不生效:

  1. jest.mock提升机制冲突:jest.mock 会被Jest自动提升到所有代码执行前运行,你在外部定义的mockRecordsFindAll变量在jest.mock执行时还未完成初始化,拿到的值是undefined
  2. findAll赋值语法错误:你写的findAll: () => mockRecordsFindAll 相当于调用records.findAll()时返回的是mock函数本身,而不是执行mock函数得到的结果,和预期逻辑完全不符
  3. 异步返回与属性匹配错误:Sequelize的findAll是异步方法返回Promise,你的mock需要返回Promise对象;另外数组长度属性是length不是size,原测试能通过属于巧合

解决方案

有两种常用实现方式都可以满足自定义返回值的需求:

方案1:从mock的initModels中获取findAll引用(更稳妥,无变量提升问题)

const repository = require('../../../src/db/repository/repository');
const initModels = require('../../../src/db/model/init-models');

// 先mock initModels
jest.mock('../../../src/db/model/init-models', () => {
    // 内部定义mock函数
    const mockRecordsFindAll = jest.fn();
    return function() { 
        return {
            records: {
                findAll: mockRecordsFindAll
            }
            // 其他模型的mock逻辑补充在这里
        }
    }
});

describe('fetchRecords', () => {
    let mockFindAll;
    beforeEach(()=> {
        // 每次测试前获取最新的mock函数实例,重置状态
        mockFindAll = initModels().records.findAll;
        mockFindAll.mockReset();
    });

    test('should return correct number of records', async () => {
        // 异步方法用mockResolvedValue设置返回值
        mockFindAll.mockResolvedValue([1,2,3]);
        const result = await repository.fetchRecords();
        // 数组长度用length属性
        expect(result.length).toStrictEqual(3);
    });

    test('should throw error when query failed', async () => {
        // 模拟抛出错误场景
        mockFindAll.mockRejectedValue(new Error('DB query error'));
        await expect(repository.fetchRecords()).rejects.toThrow('DB query error');
    });
})

方案2:使用符合Jest命名规则的外部mock变量

Jest允许在jest.mock的工厂函数中引用名称以mock开头的变量,这类变量会和jest.mock一起被提升,你原来的写法稍作修改即可生效:

// 变量名必须以mock开头
const mockRecordsFindAll = jest.fn();

jest.mock('../../../src/db/model/init-models', () => {
    return function() { 
        return {
            records: {
                // 直接赋值mock函数,不要套一层箭头函数
                findAll: mockRecordsFindAll
            }
        }
    }
});

describe('fetchRecords', () => {
    beforeEach(()=> {
        mockRecordsFindAll.mockReset()
    });

    test('should return correct number of records', async () => {
        mockRecordsFindAll.mockResolvedValue([1,2,3]);
        const result = await repository.fetchRecords();
        expect(result.length).toStrictEqual(3);
    });
})

内容的提问来源于stack exchange,提问作者gzz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 04:45:04