angular: [beta.16 regression/testing] Scheduler / tick not working for code with multiple async-events
IMPORTANT: This repository’s issues are reserved for feature requests and bug reports. Do not submit support requests here, see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question.
This is pretty hard to describe, but I’m basically testing the typical Typeahead-Example everybody demonstrates. So this is my controller-code:
searchTerm = new Control();
ngOnInit() {
this.searchTerm.valueChanges
.do((val)=> console.log("Before debounce", val))
.debounceTime(200)
.do((val)=> console.log("After Debounce", val))
.switchMap((term :string) => { return this.taskService.findTasks({'q': term})})
.subscribe(() => {
});
}
and this is my test:
iit('should execute a Typeahead-Search', fakeAsync(() => {
fixture.detectChanges();
let taskList = fixture.componentInstance,
element = fixture.nativeElement;
var spy : Spy = spyOn(taskService, 'findTasks').and.callThrough();
let input = element.querySelector('#searchField');
taskList.searchTerm.updateValue("Term");
tick(500);
console.log("Input Value: ", input.value); // prints 'Input Value: ', 'Term' correctly
expect(taskService.findTasks).toHaveBeenCalledWith({'q': 'Term'});
}));
this worked perfectly fine in beta.15 but fails with beta.16 / zone0.6.12. The error message is:
Error: 1 timer(s) still in the queue.
After some debugging I think the problematic line is this one:
https://github.com/angular/zone.js/blob/master/lib/zone-spec/fake-async-test.ts#L23
As for every scheduled task the member-variable _currentTime
is increased by the passed delay. In my example the scheduleFunction
is executed twice:
First time for the valueChanges
with delay (0) and second time for the debounceTime
with delay(200). As in the mean-time there was also a call to tick(500)
the endTime sums up to 700 which will noch be reached in the test. Changing the mentioned line to:
var endTime = delay;
lets my test work properly. But I’m not sure if this maybe leads to other problems…
Current behavior
multiple async functions (valueChanges + debounceTime) break test because of buggy scheduler behaviour
Expected/desired behavior
multiple async functions should not break the scheduler
Other information
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 18
- Comments: 16 (6 by maintainers)
Commits related to this issue
- use material inputs see https://github.com/angular/angular/issues/8251 for the `tick(1000)` reason — committed to axelhodler/blabverific by deleted user 7 years ago
this is still happening in v4.
@nethulap
Your discardPeriodicTasks() tip helped me. I was dispatching KeyUp events, which would work on the first tick(500) but give the “Error: 1 periodic timers(s) still in queue” the second time I tried to dispatch same event.
Code excerpt
Test excerpt
for a quick fix for this issue call
discardPeriodicTasks()
at the end.ticking twice works for me
I’d experienced many errors like
Error: 1 timer(s) still in the queue.
as well (before beta 16); my hacky workaround had been to addtick(1000);
statements.I was able to reproduce the error way easier. The problem is when an async-event triggers another async-event (in case of the typeahead it’s the async “valueChanges”-execution that triggers the debounceTime). The following test also fails with:
Error: 1 timer(s) still in the queue.
In
fake-async-test.js
the calculated endTime is 1300: