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

如何清除Jest中jest.fn()创建的mock函数上的spy监听?

如何清除Jest中mock函数上的spy

问题描述:如果原始函数不是jest.fn(),使用jest.restoreAllMocks()可以正常生效,但如果是jest.fn()创建的函数,要如何正确清除其上的所有spy呢?
现有测试代码如下:

describe('Mock', () => {
  const mock = {
    method1: jest.fn().mockReturnValue(false),
  };
  afterEach(() => {
    // 以下方法都无法清除spy
    jest.clearAllMocks();
    jest.resetAllMocks();
    jest.restoreAllMocks();
  });
  it('默认返回false', () => {
    expect(mock.method1()).toEqual(false);
  });
  it('应用spy实现后修改返回值为true', () => {
    jest.spyOn(mock, 'method1').mockReturnValue(true);
    expect(mock.method1()).toEqual(true);
  });
  // 该测试用例执行失败
  it('每次测试后重置为原始返回值', () => {
    expect(mock.method1()).toEqual(false);
  });
});

原因说明

原有三个方法失效的核心逻辑如下:

  • jest.clearAllMocks():仅清除mock函数的调用记录、传参、返回值历史,不会修改mock的实现逻辑
  • jest.resetAllMocks():会将mock函数的实现重置为返回undefined的空函数,不会回到你初始定义的返回false的实现
  • jest.restoreAllMocks():默认配置下仅能恢复通过jest.spyOn包装的非mock原始函数,且需要开启全局配置restoreMocks: true才会自动生效,对本身就是jest.fn()创建的mock函数默认不处理

推荐解决方案

方案1:每次测试前重新初始化mock(最稳妥,无状态污染)

将mock对象的初始化逻辑放到beforeEach中,保证每次测试运行时拿到的都是初始状态的mock:

describe('Mock', () => {
  let mock;
  // 每次测试前重新创建mock,自然携带初始实现
  beforeEach(() => {
    mock = {
      method1: jest.fn().mockReturnValue(false),
    };
  });

  it('默认返回false', () => {
    expect(mock.method1()).toEqual(false);
  });

  it('应用spy实现后修改返回值为true', () => {
    jest.spyOn(mock, 'method1').mockReturnValue(true);
    expect(mock.method1()).toEqual(true);
  });

  it('每次测试后重置为原始返回值', () => {
    expect(mock.method1()).toEqual(false);
  });
});

方案2:手动重置mock实现

如果需要复用顶层定义的mock,可以提前保存初始实现,在afterEach中手动恢复:

describe('Mock', () => {
  // 保存初始实现
  const originalMethod1 = jest.fn().mockReturnValue(false);
  const mock = {
    method1: originalMethod1,
  };

  afterEach(() => {
    // 每次测试后恢复初始实现
    mock.method1.mockImplementation(originalMethod1);
  });

  it('默认返回false', () => {
    expect(mock.method1()).toEqual(false);
  });

  it('应用spy实现后修改返回值为true', () => {
    jest.spyOn(mock, 'method1').mockReturnValue(true);
    expect(mock.method1()).toEqual(true);
  });

  it('每次测试后重置为原始返回值', () => {
    expect(mock.method1()).toEqual(false);
  });
});

方案3:开启restoreMocks配置

在jest配置文件(jest.config.js、jest.config.ts等)中添加restoreMocks: true,开启后jest.restoreAllMocks()会自动将所有jest.spyOn创建的spy恢复到spy执行前的实现,无需额外手动处理:

// jest.config.js
module.exports = {
  // 其他配置
  restoreMocks: true
}

开启后原测试代码中的jest.restoreAllMocks()即可正常生效。


内容的提问来源于stack exchange,提问作者Michał Terczyński SM

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 10:48:02