Angular 8 Жасмин / Карма шпионские вопросы поведения - PullRequest
1 голос
/ 09 июля 2020

У меня есть директива с настраиваемыми debounce декораторами. Это довольно простая директива, которая прослушивает событие «scroll».

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);
    }
}

В моем тесте я предполагаю, что this.scrolled.emit() будет вызываться всякий раз, когда вызывается onScroll. Очевидно, что это не так.

С противодействием похоже, что onScroll может вызываться несколько раз из spyOn, а this.scrolled генерировать только один раз. Например, если я запускаю события прокрутки 2 раза в моем тесте с интервалами 300 мс, onScroll вызывается 2 раза, а this.scrolled имеет только 1 emit . 1 испускание, конечно, желательное поведение, но почему onScroll вызывается дважды. Когда приложение фактически запущено в браузере - вместо тестов - onScroll на самом деле вызывается только один раз.

Почему это?!

Детали теста можно просмотреть на StackBliz.io

1 Ответ

1 голос
/ 09 июля 2020

Это очень интересный вопрос!

Чтобы лучше понять, как все работает, я бы рекомендовал открыть этот разветвленный 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 Dev Tools

Это это то, что происходит после обновления sh приложения:

  • descriptor.value; достигнуто; это означает, что шпион будет применен к вновь созданной функции:
descriptor.value = function () { /* this will be spied */ }
  • vsCss.triggerEventHandle (строка 36) достигнуто

  • var callData = { достигнуто из-за шпиона.

  • calls.push(context); достигнуто, что означает, что шпион (onScroll) был вызван

  • var params = []; достигнуто, потому что шпион был определен с callThrough(), что означает, что будет использоваться исходная реализация

  • vsCss.triggerEventHandler (строка 40) достигнуто

  • var callData = { достигнуто, из-за шпиона

  • calls.push(context); достигнуто снова; если бы мы навели курсор на calls, мы бы увидели, что в нем уже есть элемент (из предыдущего vsCss.triggerEventHandle), следовательно, длина calls 'будет равна 2

  • var params = []; - используется оригинальная реализация

  • var callData = { достигнуто; на этот раз это шпион, который мы использовали на Subject (т.е. EventEmitter); в этом можно убедиться, наведя курсор на this с object: this

  • calls.push(context); - calls принадлежит шпионскому методу Субъекта

  • var callData = { достигнуто; на этот раз шпион принадлежит onDummy методу

  • calls.push(context); - onDummy шпиону

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...