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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 04:15:05