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

使用Jest模拟Express控制器导入的ES模块失败求助

解决Jest模拟Express控制器中ESM模块失效的问题

问题原因

Jest处理ES模块时,模块导入是静态的。如果在mock设置完成前就导入了依赖目标模块的代码(比如你的Express服务器或控制器),原始模块会被提前加载,导致mock规则无法生效。你当前的测试直接使用了提前导入的server,但server依赖的控制器已经加载了未被mock的module_to_mock.js。

解决方案

核心是先设置mock规则,再动态导入依赖该mock的模块,同时修正mock的导出格式以匹配ESM的默认导出规范。

修改后的测试代码

// message_controller.test.js
// 1. 先配置mock,注意返回格式要匹配ESM默认导出结构
jest.unstable_mockModule('./module_to_mock.js', () => ({
  default: jest.fn().mockReturnValue(true)
}));

test('Mock successfully', async () => {
  // 2. 在测试内部动态导入server和被mock的模块
  const { default: server } = await import('./server.js'); // 替换为你的实际server文件路径
  const { default: moduleToMock } = await import('./module_to_mock.js');
  
  const messageToSend = 'hello';
  const response = await server.post('/message').send({ message: messageToSend });

  expect(response.body.message).toEqual(`Mock works: ${messageToSend}`);
  // 可选:验证mock函数确实被调用过
  expect(moduleToMock).toHaveBeenCalled();
});

关键注意事项

  • 禁止在测试文件顶部静态导入server或控制器,必须在jest.unstable_mockModule之后用await import()动态导入,确保mock规则在模块加载前生效。
  • jest.unstable_mockModule的回调函数必须返回包含default字段的对象,对应原模块的默认导出,这是ESM模块的导出要求。
  • 如果你的server文件在启动时就加载了控制器,动态导入server会确保控制器在mock设置完成后才被加载,从而应用mock规则。

内容的提问来源于stack exchange,提问作者Yılmaz Kasap

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 17:42:11