Jest手动Mock在ES6 import下失效,CommonJS正常的问题排查
Jest ES6 Import模式下手动Mock失效的排查与解决
核心问题分析
报错TypeError: fetchData.mockResolvedValueOnce is not a function说明ES6模式下Jest未正确加载__mocks__目录中的Mock模块,导致fetchData不是Jest mock函数实例。以下是常见问题及修复方案:
1. Jest未配置ES模块支持
Jest默认优先处理CommonJS模块,若项目启用ES模块(如package.json中设置"type": "module"),需调整Jest配置以兼容ES语法:
在jest.config.js中添加/修改以下配置:
module.exports = { testEnvironment: 'node', transform: { '^.+\\.(js|jsx)$': 'babel-jest', // 用babel转译ES模块 }, moduleFileExtensions: ['js', 'json', 'jsx'], extensionsToTreatAsEsm: ['.js'], // 标记.js文件为ES模块 };
同时安装必要依赖:npm install --save-dev babel-jest @babel/core @babel/preset-env,并创建.babelrc文件:
{ "presets": [["@babel/preset-env", {"targets": {"node": "current"}}]] }
2. Mock模块与原模块导出方式不匹配
ES模块的导出语法与CommonJS不同,需保证Mock模块的导出方式和原模块完全一致:
若原模块(utils/fetch-data.js)是默认导出:
// 原模块ES语法 export default async function fetchData() { // 外部API调用逻辑 }
Mock模块(utils/__mocks__/fetch-data.js)需对应默认导出:
// Mock模块ES语法 export default jest.fn();
若原模块是命名导出:
// 原模块ES语法 export async function fetchData() { // 外部API调用逻辑 }
Mock模块需对应命名导出:
// Mock模块ES语法 export const fetchData = jest.fn();
3. 测试文件中Mock调用时机错误
ES模块是静态加载的,jest.mock必须在import语句之前执行(Jest会自动提升jest.mock调用,但需确保语法正确):
正确的测试文件(currency.test.js)写法:
// 先声明Mock,再导入模块 jest.mock('./utils/fetch-data'); import fetchData from './utils/fetch-data'; import currency from './currency'; test('测试货币转换逻辑', async () => { // 配置Mock返回值 fetchData.mockResolvedValueOnce({ rate: 1.2 }); const result = await currency.getConvertedAmount(100); expect(result).toBe(120); });
4. 路径引用错误
确保jest.mock和import的相对路径与文件结构完全一致,避免因路径错误加载原模块而非Mock模块。
内容的提问来源于stack exchange,提问作者Mohamed
相关产品推荐
相关产品推荐

