Jest中无法在it用例内使用jest.mock,如何按场景动态设置mock返回值?
Jest 动态 mock 不同场景返回值实现方案
jest.mock 存在静态提升机制,会在测试文件所有代码执行前优先处理,因此写在 it 测试用例内部的 jest.mock 无法按预期生效,可通过以下两种主流方案实现需求:
方案1:顶层预声明 mock 函数,用例内动态修改返回值(最推荐)
该方案性能更高、逻辑更简洁,适合绝大多数场景:
- 顶层先 mock 整个模块,将需要动态调整的方法替换为 Jest 模拟函数,可同时配置默认返回值
// 测试文件顶层 jest.mock('@lib/commons', () => ({ callApi: jest.fn().mockResolvedValue({id: 'default-value'}), validateSchema: jest.fn().mockReturnValue(true) })); // 引入 mock 后的方法 const { callApi, validateSchema } = require('@lib/commons'); // 可选:每次测试用例执行前重置 mock 状态,避免不同用例的 mock 配置互相影响 beforeEach(() => { jest.clearAllMocks(); });
- 在不同测试用例中直接修改 mock 函数的返回值即可
it("测试接口返回正常业务数据", async () => { callApi.mockResolvedValue({id: 'scene1', data: [1,2,3]}); // 测试逻辑 }); it("测试接口请求异常场景", async () => { callApi.mockRejectedValue(new Error('网络请求失败')); // 测试逻辑 }); it("测试 schema 校验不通过场景", () => { validateSchema.mockReturnValue(false); // 测试逻辑 });
- 可直接封装成可复用的配置函数:
// 封装 mock 配置工具 const mockCommonsConfig = (params = {}) => { const { callApiResponse = {id: 'default'}, validateResult = true } = params; callApi.mockResolvedValue(callApiResponse); validateSchema.mockReturnValue(validateResult); }; // 测试用例中直接调用 it("使用封装函数配置mock", async () => { mockCommonsConfig({ callApiResponse: {id: 'custom', name: '测试数据'}, validateResult: false }); // 测试逻辑 });
方案2:用 jest.doMock 实现用例内独立 mock
如果某类场景需要完全重写整个模块的 mock 内容,可使用不会被静态提升的 jest.doMock,注意必须在 mock 完成后再引入目标模块:
it("特殊场景完全重写模块mock", async () => { jest.doMock('@lib/commons', () => ({ callApi: jest.fn().mockResolvedValue({id: 'special'}), validateSchema: jest.fn().mockReturnValue(false), extraMethod: jest.fn().mockReturnValue('额外mock方法') })); // 必须在doMock之后再引入模块,才能拿到最新的mock结果 const { callApi, extraMethod } = require('@lib/commons'); // 如果是ESModule import语法,改为:const commons = await import('@lib/commons'); // 测试逻辑 });
内容的提问来源于stack exchange,提问作者Prakhar
相关产品推荐
相关产品推荐

