开玩笑 - 使用 spyOn 函数时,确保不调用被监视的函数

Posted

技术标签:

【中文标题】开玩笑 - 使用 spyOn 函数时,确保不调用被监视的函数【英文标题】:Jest - when using spyOn function ensure the spied one is not called 【发布时间】:2019-09-15 02:08:51 【问题描述】:

来自 Jest 笔记:注意:默认情况下,jest.spyOn 也调用 spie 方法。

在我的 Angular 组件中。

ngAfterViewInit(): void 
  this.offsetPopoverPosition();

在我的规范中:

it('ngAfterViewInit() method should call offsetPopoverPosition() method', () => 
    const mockListener = jest.spyOn(cmp, 'offsetPopoverPosition');
    const spy = mockListener.mockImplementation(() => 
      console.log('in the mock');
    );

    cmp.ngAfterViewInit();
    expect(spy).toHaveBeenCalled();
  );

简单。然而,原始函数仍在被调用。 我检查了 Jest 23.x 文档: https://jestjs.io/docs/en/23.x/jest-object#jestspyonobject-methodname https://jestjs.io/docs/en/23.x/mock-function-api#mockfnmockimplementationfn

互联网上的例子很少,但我无法阻止 jest 调用原始的 offsetPopoverPosition() 方法。

有什么想法吗?

我正在交叉链接到 Jest github 问题,该问题由于某种原因已关闭而未解决。

Jest spyOn() calls the actual function instead of the mocked

【问题讨论】:

组件构造函数中offsetPopoverPosition是否绑定到this 不,它只在 ngAfterViewInit 中调用 ...啊,看起来cmp 是一个实例,所以无论如何它都不会产生影响。从我所看到的代码来看,它应该可以工作。 (JonathanHolvey在github链接中的代码不起作用的原因是因为processVisit直接调用saveVisit所以模拟saveVisit的模块导出没有任何效果......这不适用于您的代码,因为你的两个函数都是我所看到的类方法) 【参考方案1】:

根据我的经验,问题在于您正在重置原始模拟的意图。当你创建一个间谍时,它有自己的实现,通过用 mockImplementation 覆盖它,我已经体验过你描述的场景 - 相反,试试这个:

cmp.offsetPopoverPosition = jest.fn().mockImplementation(() => 
      console.log('in the mock');
    );
const mockListener = jest.spyOn(cmp, 'offsetPopoverPosition');
// ... do work
expect(mockListener).toHaveBeenCalled[Times,With]()

这也假设cmp 是组件的一个实例,而不仅仅是它的定义参考

编辑:请注意,在您正在测试的组件内模拟出消息函数是一种错误的单元测试方法。而不是测试与sameComponent.method 的通信 - 测试链接方法使用的任何消息在被测试组件之外 - 使用简短的问题内容,​​请忽略我给出的测试方法建议,如果它的阅读茶叶,与您的单元测试设计无关

【讨论】:

如果是这样,那么spyOn返回的spyInstance对象提供的mockImplementation有什么意义呢?此外,在您的示例中,您不是在模拟原始 cmp 中的原始 offsetPopoverPosition()`。

以上是关于开玩笑 - 使用 spyOn 函数时,确保不调用被监视的函数的主要内容,如果未能解决你的问题,请参考以下文章

Jest spyOn 函数调用

jest中的mock,jest.fn()jest.spyOn()jest.mock()

jest中的mock,jest.fn()jest.spyOn()jest.mock()

用玩笑测试打字稿中的私有函数

jest中的mock,jest.fn()jest.spyOn()jest.mock()

如何在不使用 Angular 的 spyOn 的情况下检查服务中的方法是不是在 Jasmine 单元测试中被调用?