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

如何在Jest中模拟动态导入模块的依赖(Mock Math.pi())

如何在模块导入阶段模拟Math.pi()的返回值?

由于module-b在导入时就会执行Math.pi()并将结果赋值给piVal,所以必须先完成对module-a的mock,再动态导入module-b,才能让mock生效。以下是基于Jest的具体实现方案:

修改后的测试代码

describe('module b', () => {
  it('返回mock后的计算结果', () => {
    // 提前mock module-a的默认导出
    jest.mock('./module-a', () => ({
      default: class MockMath {
        static pi() {
          return 100; // 自定义mock的返回值
        }
      }
    }));

    // 动态导入module-b,此时piVal会使用mock后的pi()结果
    return import('./module-b').then(module => {
      expect(module.doSomeCalc(20)).toBe(120); // 100 + 20 = 120
    });
  });

  it('返回原始逻辑的计算结果', () => {
    // 清除mock,恢复原模块
    jest.unmock('./module-a');
    // 重置模块缓存,避免之前的导入影响
    jest.resetModules();

    return import('./module-b').then(module => {
      expect(module.doSomeCalc(20)).toBe(23.14); // 3.14 + 20 = 23.14
    });
  });
});

关键注意点

  • mock时机必须早于模块导入:module-b的初始化逻辑(执行Math.pi())在导入时就会触发,所以mock操作一定要在import('./module-b')之前完成。
  • 匹配原模块的调用方式:原代码中直接调用Math.pi()(将pi作为静态方法),所以mock时要把pi定义为模拟类的静态方法,确保调用逻辑一致。
  • 重置模块缓存:如果在多个测试用例中切换mock和原模块,需要用jest.resetModules()清空模块缓存,避免之前的导入结果残留。

其他测试框架适配

如果使用Vitest,逻辑完全一致,仅需将jest.mock()替换为vi.mock(),jest.unmock()替换为vi.unmock(),jest.resetModules()替换为vi.resetModules()即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 04:20:56