如何使用Jest模拟导出的const常量以测试FOO函数?
如何用Jest模拟ES模块中的常量导出
核心问题原因
你之前的写法无效,是因为ES模块的导入是静态绑定的:当你先导入FOO时,foo.mjs已经完成加载,FOO的闭包已经捕获了原始BAR的引用,后续再调用jest.mock无法修改这个已绑定的引用。jest.mock需要在目标模块导入前执行,才能替换掉原始模块的导出。
正确解决方案
1. 调整jest.mock的位置到模块作用域顶部
把jest.mock放在import { FOO }之前,确保Jest在加载foo.mjs时就替换掉bar.mjs的导出:
import { jest } from '@jest/globals'; // 先执行mock,再导入目标模块 jest.mock('./bar.mjs', () => ({ BAR: 'mocked' })); import { FOO } from "./foo.mjs"; test('Mock test', () => { console.log(FOO()); // 输出 'mocked' });
2. 确保Jest配置支持ES模块
如果你的项目使用ESM(比如文件后缀为.mjs,或package.json中设置"type": "module"),需要在Jest配置中开启ESM支持:
- 创建
jest.config.js文件:
export default { transform: {}, // 禁用默认的babel转换,ESM不需要 moduleFileExtensions: ['mjs', 'js'], testEnvironment: 'node' };
- 或者在
package.json中添加Jest配置:
"jest": { "transform": {}, "moduleFileExtensions": ["mjs", "js"], "testEnvironment": "node" }
补充说明
Jest的模块mock机制是在模块加载阶段替换原始模块,所以必须保证jest.mock的执行时机早于目标模块的导入。只要遵循这个顺序,无论导出的是const还是let/var,都能被正确mock。
内容的提问来源于stack exchange,提问作者Umberto Fontanazza
相关产品推荐
相关产品推荐

