繁体   English   中英

Angular 8 Jasmine/Karma spyOn 行为问题

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM