Jest中取消Mocked函数后无法恢复原始行为返回undefined问题
问题原因
- 你在顶部使用
jest.mock("./MyService")全局mock了整个模块,该操作会直接替换模块的所有导出内容,类、方法的原始实现会被覆盖为Jest默认的空mock函数,本身没有留存原始实现的备份,调用mockRestore自然无法恢复原有逻辑。 mockRestore方法仅对jest.spyOn创建的监听式mock生效,你直接赋值给MyService.f1的mock函数没有关联原始实现的备份,调用后只会把mock函数重置为空实现,执行后自然返回undefined。f1是MyService类的原型实例方法,你直接挂载在类构造函数上的MyService.f1和类实例调用的this.f1/new MyService().f1不是同一个对象,mock本身就没有对应到实际调用的方法位置。
解决方案
方案1:优先使用jest.spyOn做临时mock(最推荐)
不要全局mock整个MyService模块,需要临时mock某个方法时通过spyOn创建监听,自带原始实现备份,用完直接restore即可恢复:
import MyService from './MyService' test('测试示例', async () => { // 监听原型上的f1方法,临时mock返回值 const f1Spy = jest.spyOn(MyService.prototype, 'f1').mockResolvedValueOnce([]) await OtherService.f3() // 恢复f1的原始实现 f1Spy.mockRestore() // 仅mock内部的f2方法 const f2Spy = jest.spyOn(MyService.prototype, 'f2').mockResolvedValueOnce([/* 你的模拟数据 */]) const serviceInstance = new MyService() // 此时调用f1会走原始逻辑,内部调用的f2返回模拟值 const result = await serviceInstance.f1('测试参数') // 恢复f2的原始实现 f2Spy.mockRestore() })
方案2:必须全局mock时保留原始实现引用
如果业务场景必须要全局mock整个模块,在声明mock时导入并留存原始实现:
jest.mock('./MyService', () => { // 导入原始模块内容 const originalModule = jest.requireActual('./MyService') return { ...originalModule, // 这里可以添加需要全局默认mock的内容,没有特殊需求直接返回所有原始内容即可 } })
后续临时mock仍然使用方案1的jest.spyOn操作即可。
辅助配置避免mock互相影响
可以在Jest配置中开启restoreMocks: true,每个测试用例执行完毕后会自动恢复所有spyOn创建的mock的原始实现,无需手动调用mockRestore,避免用例之间的mock污染。
内容的提问来源于stack exchange,提问作者Web Jigooli
相关产品推荐
相关产品推荐

