如何在每次测试之前重置 Jest 模拟函数调用计数

Posted

技术标签:

【中文标题】如何在每次测试之前重置 Jest 模拟函数调用计数【英文标题】:How to reset Jest mock functions calls count before every test 【发布时间】:2018-05-28 12:14:53 【问题描述】:

我是 Jest 的新手,我试图用它来测试一个函数是否被调用。我注意到 mock.calls.length 并没有为每个测试重置,而是在累积。如何在每次测试之前将其设为 0?我不希望我的下一个测试取决于之前的结果。

我知道 Jest 中有 beforeEach - 我应该使用它吗?重置 mock.calls.length 的最佳方法是什么?谢谢你。

代码示例:

Sum.js:

import local from 'api/local';

export default 
  addNumbers(a, b) 
    if (a + b <= 10) 
      local.getData();
    
    return a + b;
  ,
;

Sum.test.js

import sum from 'api/sum';
import local from 'api/local';
jest.mock('api/local');

// For current implementation, there is a difference 
// if I put test 1 before test 2. I want it to be no difference

// test 1
test('should not to call local if sum is more than 10', () => 
  expect(sum.addNumbers(5, 10)).toBe(15);
  expect(local.getData.mock.calls.length).toBe(0);
);

// test 2
test('should call local if sum <= 10', () => 
  expect(sum.addNumbers(1, 4)).toBe(5);
  expect(local.getData.mock.calls.length).toBe(1);
);

【问题讨论】:

【参考方案1】:

我找到了一种处理方法:在每次测试后清除模拟函数:

添加到 Sum.test.js:

afterEach(() => 
  local.getData.mockClear();
);

如果您想在每次测试后清除所有模拟函数,请使用clearAllMocks

afterEach(() => 
  jest.clearAllMocks();
);

【讨论】:

很好奇是否有办法为所有模拟对象的方法做到这一点。当我尝试local.mockClear() 时,它不起作用。 你试过使用jest.clearAllMocks()吗?文档:jestjs.io/docs/en/jest-object#jestclearallmocks @AlexEfremov,非常感谢jest.clearAllMocks() 功能!我一直在将mockClear() 用于jest.mock 类,显然模拟没有以某种方式完全清除(模拟类中的间谍函数调用没有被清除)。这导致了非常烦人的对象实例差异错误:Compared values have no visual difference.. 为了增强这个答案,我更新了我的jest.config.js 属性resetMocks: true【参考方案2】:

正如@AlexEfremov 在 cmets 中指出的那样。您可能希望在每次测试后使用clearAllMocks

afterEach(() => 
    jest.clearAllMocks();
);

请记住,这将清除您拥有的每个模拟函数的调用计数,但这可能是正确的方法。

【讨论】:

【参考方案3】:

您可以将 Jest 配置为在每次测试后重置模拟,方法是将其放入您的 jest.config.js

module.exports = 
  resetMocks: true,
;

这里是这个配置参数的文档: https://jestjs.io/docs/en/configuration#resetmocks-boolean

resetMocks [布尔]

默认值:假

在每次测试前自动重置模拟状态。相当于在每次测试之前调用 jest.resetAllMocks() 。这将导致任何 mock 的虚假实现被移除,但不会恢复它们的初始实现。

【讨论】:

我对此不是 100% 确定的,但这实际上不会重置模拟。 I.E 重置您拥有的任何模拟实现?如果您在实际测试之外设置模拟的实现,它将被重置(如果它相当于 ech 测试之前的resetAllMocks()。作者似乎正在寻找一种方法来清除调用计数器,但是保持他们的模拟实现。同样,不是 100% 肯定,但这是我对 resetAllMocks 的理解。 我在这里同意@Flux。配置clearMocks 似乎是作者想要的。【参考方案4】:

您可以在命令中添加 --resetMocks 选项: npx jest --resetMocks

在每次测试之间自动重置模拟状态。相当于 打电话给jest.resetAllMocks()

【讨论】:

以上是关于如何在每次测试之前重置 Jest 模拟函数调用计数的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Jest 中重置或清除间谍?

每次测试都是Mock模块

开玩笑的测试在调用模拟的 firebase 函数之前完成,因此失败

当模拟点击调用调用 promise 的函数时,使用 React 的 Jest 和 Enzyme 进行测试

如何使用 jest 模拟链式函数调用?

在 vue-multiselect 中测试 vuex 操作时调用了 Jest 预期的模拟函数