使用jest.unstable_mockModule模拟ES6模块不生效问题求助
问题原因
- 模块导入顺序错误
你在测试文件顶部静态导入了main模块,此时Main.mjs内部已经提前加载了原始的Responder和Notifier模块,后续再调用jest.unstable_mockModule只能影响之后的动态导入,无法替换已经加载完成的依赖,所以mock不生效。 - Mock结构不匹配原模块导出
原Notifier.mjs是默认导出一个类,你当前mock返回的是一个直接包含notify属性的对象,和原模块导出结构不一致。Main.mjs中是通过new Notifier()生成实例再调用notify,mock不符合调用逻辑。 - 未触发异常分支
你没有mockResponder模块让它抛出异常,代码不会进入catch分支,自然也不会调用notify方法。
修正后的测试代码
// test/Main.test.mjs import { jest } from '@jest/globals' describe('fetch', () => { test('Notifies on error', async () => { const mockNotify = jest.fn(); // 先mock所有依赖模块 // mock Notifier,匹配原模块的默认导出类结构 jest.unstable_mockModule('../src/Notifier.mjs', () => ({ default: class MockNotifier { notify = mockNotify } })) // mock Responder,让它的respond方法直接抛错,触发catch分支 jest.unstable_mockModule('../src/Responder.mjs', () => ({ default: class MockResponder { respond() { throw new Error('test error') } } })) // 所有依赖mock完成后,再动态导入被测的main模块 const { default: main } = await import('../src/Main.mjs'); await main.fetch(null, null, null) expect(mockNotify).toHaveBeenCalled() }) })
额外注意事项
- 开启Jest的ESM支持,需要在Jest配置中添加
extensionsToTreatAsEsm: ['.mjs'],同时运行jest时添加--experimental-vm-modules参数,示例运行命令为node --experimental-vm-modules node_modules/jest/bin/jest.js - 所有
jest.unstable_mockModule调用必须放在对应模块的导入操作之前,不管是静态导入还是动态导入 - mock返回的结构必须和原模块的导出结构完全匹配,默认导出、命名导出的对应关系都要保持一致
内容的提问来源于stack exchange,提问作者rmontgomery429
相关产品推荐
相关产品推荐

