如何在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
相关产品推荐
相关产品推荐

