[英]Angular 8 Jasmine/Karma spyOn behavior questions
我有一个带有自定义去抖动装饰器的指令。 该指令是一个相当简单的监听“滚动”事件的指令。
export class MyScrollDirective {
@Output() scrolled = new EventEmitter<any>();
@HostListener('scroll', ['$event'])
//debouce is added to prevent multiple call when scroll reach the end
//in the if statement below
@myDebounce(300)
onScroll(event) {
this.scrolled.emit(null);
}
}
在我的测试中,我假设只要调用onScroll
就会调用this.scrolled.emit()
。 显然,情况并非如此。
通过去抖动,看起来onScroll
可以从spyOn
调用多次,而this.scrolled
只发出一次。 例如,如果我在测试中以 300 毫秒的间隔触发滚动事件 2 次,则onScroll
被调用 2 次,而this.scrolled
只有 1 次emit 。 1 发射当然是期望的行为,但是如何调用onScroll
两次。 当应用程序实际在浏览器中运行时 - 而不是测试 - onScroll
实际上只被调用一次。
为什么是这样?!
测试细节可以在StackBliz.io查看
这是一个非常有趣的问题!
为了更好地理解事情是如何工作的,我建议打开这个分叉的 StackBlitz并放置这些断点:
jasmine.js
calls.push(context);
- 第 2162 行{
- 第 5972 行myDebounceDecorator.ts
descriptor.value
.值 - 第 16 行var params = [];
- 第 18 行dummy.component.spec.ts
vsCss.triggerEventHandler(...)
- 第 36 行vsCss.triggerEventHandler(...)
- 第 40 行注意:我使用过 Firefox 开发工具
这是刷新应用程序后发生的情况:
descriptor.value;
到达了; 这意味着间谍将应用于新创建的 function:descriptor.value = function () { /* this will be spied */ }
vsCss.triggerEventHandle
(第 36 行)
var callData = {
到达,因为间谍。
calls.push(context);
已到达,这意味着调用了 spy( onScroll
)
var params = [];
到达,因为 spy 是用callThrough()
定义的,这意味着将使用原始实现
vsCss.triggerEventHandler
(第 40 行)
var callData = {
到达,因为间谍
calls.push(context);
再次到达; 如果我们要通过calls
hover ,我们会看到它已经有一个元素(来自之前的vsCss.triggerEventHandle
),因此calls
的长度将为 2
var params = [];
- 使用原始实现
var callData = {
已达到; 这一次,它是我们在Subject
上使用的间谍(即EventEmitter
); 我们可以通过将鼠标悬停在object: this
this
calls.push(context);
- calls
属于 Subject 的 spied 方法
var callData = {
已达到; 这一次,spy 属于onDummy
方法
calls.push(context);
- onDummy
的间谍
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.