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

如何在Jest中将模拟函数恢复为原始值?解决静态函数Mock跨测试污染

嘿,这两个问题在Jest测试里挺常见的,我来给你拆解一下解决方案:

一、恢复普通Mock函数为原始值

根据你创建Mock的方式不同,恢复的方法也不一样,主要分两种场景:

  • 用jest.spyOn创建的Mock
    这是最省心的方式,因为jest.spyOn会自动保留原始函数的引用,测试结束后直接调用mockRestore()就能一键恢复。举个实际例子:

    // 假设我们有个工具模块utils,里面有fetchData函数
    import * as utils from './utils';
    
    test('验证fetchData被Mock后的行为', () => {
      // 创建Spy并替换为Mock实现
      const fetchSpy = jest.spyOn(utils, 'fetchData').mockResolvedValue('模拟返回数据');
      
      // 执行你的测试逻辑...
      
      // 恢复原始函数
      fetchSpy.mockRestore();
    });
    

    如果多个测试用例都用到这个Mock,你可以把恢复逻辑放到afterEach钩子中,避免重复代码:

    import * as utils from './utils';
    let fetchSpy;
    
    beforeEach(() => {
      fetchSpy = jest.spyOn(utils, 'fetchData').mockResolvedValue('模拟返回数据');
    });
    
    afterEach(() => {
      fetchSpy.mockRestore();
    });
    
    test('测试场景1', () => { /* ... */ });
    test('测试场景2', () => { /* ... */ });
    
  • 手动赋值的Mock(比如直接用jest.fn()替换)
    如果你是直接把函数替换成jest.fn(),那得提前手动保存原始函数的引用,测试结束后再赋值回去:

    import * as utils from './utils';
    
    // 提前保存原始函数
    const originalFetchData = utils.fetchData;
    
    test('测试手动Mock的函数', () => {
      // 替换为Mock函数
      utils.fetchData = jest.fn().mockResolvedValue('模拟返回数据');
      
      // 执行测试逻辑...
      
      // 恢复原始函数
      utils.fetchData = originalFetchData;
    });
    
二、恢复类的静态函数Mock

类的静态函数属于类本身的属性,Mock后会全局共享,所以必须确保每个测试用例结束后都清理恢复,这里推荐两种可靠的方法:

  • 优先用jest.spyOn + mockRestore()
    这是最稳妥的方式,spyOn会帮你保留原始静态方法的引用,测试后调用mockRestore()就能恢复原状,完全不会影响其他测试:

    import User from './User';
    
    test('测试A:Mock User.removeInstance静态方法', () => {
      // 创建静态方法的Spy并替换为自定义实现
      const staticSpy = jest.spyOn(User, 'removeInstance').mockImplementation(() => {
        console.log('这是Mock的静态方法');
        return true;
      });
      
      // 执行测试A的逻辑...
      
      // 恢复原始静态方法
      staticSpy.mockRestore();
    });
    
    test('测试B:使用原始的User.removeInstance', () => {
      // 这里调用的已经是类定义的原始方法,不会被测试A的Mock影响
      User.removeInstance();
    });
    

    要是多个测试都需要Mock这个静态方法,同样可以把spyOn放到beforeEach,mockRestore()放到afterEach,保证每个测试都是独立干净的状态。

  • 手动保存原始静态方法再恢复
    如果你是直接手动替换静态方法(比如User.removeInstance = jest.fn()),那得提前保存原始方法的引用,测试结束后赋值回去:

    import User from './User';
    
    // 保存原始静态方法
    const originalRemoveInstance = User.removeInstance;
    
    test('测试A', () => {
      User.removeInstance = jest.fn().mockReturnValue(true);
      // 执行测试逻辑...
    });
    
    afterEach(() => {
      // 恢复原始静态方法
      User.removeInstance = originalRemoveInstance;
    });
    
    test('测试B', () => {
      // 现在调用的就是原始的removeInstance了
      User.removeInstance();
    });
    

⚠️ 注意:别把jest.clearAllMocks()或者jest.resetAllMocks()和mockRestore()搞混了!前两个方法只是清除Mock的调用记录、实例和返回值,不会恢复原始函数的实现,只有mockRestore()才会把函数变回最初的样子。

内容的提问来源于stack exchange,提问作者Kourosh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 09:02:40