Jest未正确生效导入模块模拟的技术问题排查
解决Jest模块模拟未生效的问题
嘿,我一眼就瞅出问题所在了!你的模拟没生效是因为模块导入导出的方式不匹配,咱们来拆解下:
核心问题分析
你在fileImTestingAgainst.js里用的是默认导入:
import theFuncIWantToMock from 'someModule'
但在测试文件myTest.js里,jest.mock模拟的是一个包含具名导出的对象:
jest.mock('someModule', () => ({ theFuncIWantToMock: jest.fn() }))
这就导致被测试文件实际导入的并不是你模拟的那个函数——默认导入会取模块的default导出,而你模拟的是具名导出,自然断言不会生效。
两种解决方案(根据实际模块导出方式选)
情况1:someModule本身是默认导出theFuncIWantToMock
如果原模块是默认导出这个函数,那你需要修改测试里的jest.mock,让它直接返回模拟函数作为默认导出:
// myTest.js // 直接把模拟函数作为模块的默认导出 jest.mock('someModule', () => jest.fn()) import theFuncIWantToMock from 'someModule' import whatever from './fileImTestingAgainst' test('do my test', () => { whatever() expect(theFuncIWantToMock).toHaveBeenCalledWith(/* 你的参数 */) })
情况2:someModule本身是具名导出theFuncIWantToMock
如果原模块是通过具名导出的方式暴露这个函数,那你需要修改被测试文件的导入方式,改成具名导入:
// fileImTestingAgainst.js // 改成具名导入 import { theFuncIWantToMock } from 'someModule' export default function whatever () { console.log(theFuncIWantToMock) const myVar = theFuncIWantToMock(/* args */) // ... more stuff }
同时测试文件里的导入也要对应改成具名导入(你的jest.mock写法是对的):
// myTest.js jest.mock('someModule', () => ({ theFuncIWantToMock: jest.fn() })) // 具名导入模拟函数 import { theFuncIWantToMock } from 'someModule' import whatever from './fileImTestingAgainst' test('do my test', () => { whatever() expect(theFuncIWantToMock).toHaveBeenCalledWith(/* 你的参数 */) })
调试小技巧
你已经加了console.log(theFuncIWantToMock),可以看打印结果:
- 如果打印的是
[Function: mockConstructor],说明模拟生效了; - 如果打印的是原始函数或者
undefined,那就是导入导出的匹配还是有问题,再检查下两种方式是否对应。
内容的提问来源于stack exchange,提问作者Matt
相关产品推荐
相关产品推荐

