开玩笑 - 使用 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中的mock,jest.fn()jest.spyOn()jest.mock()
jest中的mock,jest.fn()jest.spyOn()jest.mock()