jest.fn()是一个创建存根的方法,它允许你跟踪调用,定义返回值等等。

jest.spyOn()来自 jasmine,它允许你将 现有的方法对象转换成间谍,这也允许你跟踪调用并重新定义原来的方法实现。

我的经验法则是: 如果您想使现有的实现成为一个间谍,那么如果您正在构建一个 mock,那么使用 spyOn,那么使用 fn()

我对反应/前端项目中这两个功能的简单理解如下:

jest.fn()

  • 您希望模拟一个函数,但实际上并不关心该函数的原始实现(它将被 jest.fn()覆盖)
  • 通常 只是模拟返回值
  • 如果您想在测试中移除对后端(例如,在调用后端 API 时)或第三方库的依赖关系,那么这非常有帮助
  • 如果您想进行 真的单元测试,这也是非常有帮助的。您不关心您测试的单元调用的某个函数是否正常工作,因为这不是它的责任的一部分。

jest.spyOn()

  • 该函数的原始实现与您的测试相关,但是:
    • 你想添加你自己的实现只是为了一个特定的场景,然后通过 mockRestore()再次重置它(如果你只是使用一个 jest.spyOn()而没有进一步嘲弄它,它仍然会默认调用原来的函数)
    • 您只需查看函数是否被调用
    • ...
  • 我认为这对于集成测试特别有帮助,但是 没有只对他们有帮助!

(好的博客文章: https://medium.com/@rickhanlonii/understanding-jest-mocks-f0046c68e53c)

据我所知,唯一的区别是 你可以恢复原来的功能jest.spyOn,你不能与 jest.fn

假设我们有一些钩子,在组件被渲染时调用函数,这里我们只检查函数被调用,我们不测试那个函数。

另一种情况下,如果我们想要原始函数来测试它是如何工作的,我们需要在一个测试文件中同时使用这两种方法。

真正的方法:

myMethod() {
return 33;
}

jest.fn()

const myMethod = jest.fn().mockImplementation(() => 25);
const result = myMethod();
expect(result).toBe(25);

如果我们现在想测试 real myMethod,我们不能用 jest.fn ()将它恢复到正常状态。

关于间谍还有一件事:

const spy_myMethod = jest.spyOn(component, "myMethod").mockImplementation(() => 25);
const result = myMethod();
expect(result).toBe(25);

现在,如果我们想要原始的 myMethod

spy_myMethod.mockRestore();
const result = myMethod();
expect(result).toBe(33);