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

Jest.doMock无法条件化模拟JSON导入问题排查与解决

问题:Jest无法在单个测试用例中条件化模拟JSON导入

我来帮你拆解这个问题——你遇到的核心问题是模块加载时机导致的mock失效,下面详细分析原因和解决方案:

问题回顾

你的待测试代码逻辑是导入JSON数据,异步返回数据或抛出错误:

import data from '../data/mock.json';
// 异步函数
export const something = async () => {
  try {
    if (!data) {
      throw 'error is here!';
    }
    return data;
  } catch (error) {
    return error;
  }
};

测试代码尝试用jest.doMock为不同用例设置不同的JSON模拟数据,但发现mock并未生效;全局mock可以工作,但无法区分用例。

为什么你的mock没生效?

关键点在于:你在测试文件顶部静态导入了something函数,这会在Jest执行任何测试代码之前就加载handler.js模块,而handler.js又会立刻加载原始的mock.json。

后续你在测试用例里设置的jest.doMock和重新import mock.json,都不会影响已经加载完成的something函数——它已经绑定了最初的data引用,所以mock根本没生效。

解决方案:动态导入目标函数

要实现不同测试用例的条件化mock,你需要延迟导入something函数,确保它在你设置好mock之后才被加载。具体步骤如下:

  1. 移除测试文件顶部的静态import { something } from './handler';
  2. 在每个测试用例内部,先设置jest.doMock,再通过import()动态导入something
  3. 保留beforeEach里的jest.resetModules(),确保每个测试用例的模块环境相互隔离

修改后的测试代码

describe('handler: something', () => {
  beforeEach(() => {
    jest.resetModules();
  });

  describe('on something', () => {
    it('should return data', async () => {
      const data = [
        { id: 1, price: '1', },
        { id: 2, price: '2', },
      ];
      // 1. 先设置mock
      jest.doMock('../data/mock.json', () => {
        return { __esModule: true, default: data, };
      });
      // 2. 动态导入目标函数
      const { something } = await import('./handler');
      // 3. 执行断言
      await expect(something()).resolves.toEqual(data);
    });

    it('should return error', async () => {
      jest.doMock('../data/mock.json', () => ({
        __esModule: true, default: undefined,
      }));
      // 动态导入
      const { something } = await import('./handler');
      await expect(something()).resolves.toBe('error is here!');
    });
  });
});

补充说明

  • jest.resetModules()会在每个测试用例前重置模块缓存,确保每次动态导入都是全新的模块实例,不会受到之前测试用例的mock影响
  • 因为JSON文件在ES模块中是作为默认导出的,所以mock时必须设置__esModule: true和default属性,这部分你之前的写法是正确的
  • 待测试代码不需要做任何修改,保持原来的逻辑即可

这样调整后,每个测试用例都会先设置好对应的mock数据,再加载handler模块,此时something函数引用的就是你mock后的data,就能实现条件化的模拟了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 19:02:50