Reputation: 223
I have a directive with custom debounce decorators. The directive is a fairly simple that listen on "scroll" event.
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);
}
}
In my test, I have an assumption that this.scrolled.emit()
will be called whenever onScroll
is called. Obviously this is not the case.
With the debounce, it looks like onScroll
can be called multiple times from spyOn
while this.scrolled
only emit once. For example, if I trigger scroll events 2 times in my test within 300ms intervals, the onScroll
is called 2 time while the this.scrolled
has only 1 emit. The 1 emit is of course desired behavior, but how come onScroll
is called twice. When the app is actually running in browser - instead of tests - the onScroll
is actually called only once.
Why is this?!
The test detail can be view at StackBliz.io
Upvotes: 1
Views: 150
Reputation: 11979
This is a very interesting question!
In order to get a better understanding of how things work, I'd recommend opening this forked StackBlitz and place these breakpoints:
jasmine.js
calls.push(context);
- line 2162{
- line 5972myDebounceDecorator.ts
descriptor.value
- line 16var params = [];
- line 18dummy.component.spec.ts
vsCss.triggerEventHandler(...)
- line 36vsCss.triggerEventHandler(...)
- line 40Note: I've used Firefox Dev Tools
This is what happens after you refresh the app:
descriptor.value;
is reached; this means that the spy will be applied on the newly created function:descriptor.value = function () { /* this will be spied */ }
vsCss.triggerEventHandle
(line 36) is reached
var callData = {
is reached, because of the spy.
calls.push(context);
is reached, which means the spy(onScroll
) was called
var params = [];
is reached, because the spy was defined with callThrough()
, which means that the original implementation will be used
vsCss.triggerEventHandler
(line 40) is reached
var callData = {
is reached, because of the spy
calls.push(context);
is reached again; if we were to hover over calls
, we'd see that it already has an element(from the previous vsCss.triggerEventHandle
), hence the calls
' length will be 2
var params = [];
- the original implementation is used
var callData = {
is reached; this time, it's the spy what we used on the Subject
(i.e EventEmitter
); we can be sure of this by hovering over this
from object: this
calls.push(context);
- calls
belongs to the Subject's spied method
var callData = {
is reached; this time, the spy belongs to onDummy
method
calls.push(context);
- onDummy
's spy
Upvotes: 1