'Angular testing async function generate error - 1 periodic timer(s) still in the queue
I'm trying to test that two async functions. The problem is that one of the functions is called every 10 seconds automatically. I tried to use tick() or flush() but I still get the same error: 1 periodic timer(s) still in the queue. How can I resolve it? My code:
ngOnInit(): void {
const dialogRef = this.openProgressDialog();
this.getSubscription = this.getAll();
dialogRef.close();
this.postSubscription = interval(10000).subscribe(() => {
this.sendAll();
this.dataSource.data = this.jobs;
this.table.renderRows();
});
}
The test:
test("test", fakeAsync(() => {
const getSpy = spyOn(otdRepositoryMock, "getAll").and.returnValue(of(jobs));
const getSubscribeSpy = spyOn(otdRepositoryMock.getAll(), "subscribe");
const postSpy = spyOn(otdRepositoryMock, "sendAll").and.returnValue(of(jobs));
const postSubscribeSpy = spyOn(otdRepositoryMock.sendAll([2]), "subscribe");
component.ngOnInit();
//tick();
//flush();
expect(getSpy).toHaveBeenCalled();
expect(getSubscribeSpy).toHaveBeenCalled();
expect(postSpy).toHaveBeenCalled();
expect(postSubscribeSpy).toHaveBeenCalled();
}));
Solution 1:[1]
In short, you DON'T need flush, you DO need tick() and you should add the following to the bottom of your test, following your expectations:
discardPeriodicTasks();
This will clear out any remaining timers you have before executing the next test.
So in your example (edited for brevity):
test("test", fakeAsync(() => {
const getSpy = ...
component.ngOnInit();
tick(10000);
expect(getSpy).toHaveBeenCalled() . . .
discardPeriodicTasks();
}));
Hope this helps,
Solution 2:[2]
If this.postSubscription
is a public variable, you can unsubscribe in your unit test.
test("test", fakeAsync(() => {
const getSpy = spyOn(otdRepositoryMock, "getAll").and.returnValue(of(jobs));
const getSubscribeSpy = spyOn(otdRepositoryMock.getAll(), "subscribe");
const postSpy = spyOn(otdRepositoryMock, "sendAll").and.returnValue(of(jobs));
const postSubscribeSpy = spyOn(otdRepositoryMock.sendAll([2]), "subscribe");
component.ngOnInit();
//tick();
//flush();
expect(getSpy).toHaveBeenCalled();
expect(getSubscribeSpy).toHaveBeenCalled();
expect(postSpy).toHaveBeenCalled();
expect(postSubscribeSpy).toHaveBeenCalled();
// unsubscribe
component.postSubscription.unsubscribe();
}));
If it is private, you can unsubscribe in the ngOnDestroy
and call it in the unit test.
ngOnDestroy() {
this.postSubscription.unsubscribe();
}
...
test("test", fakeAsync(() => {
const getSpy = spyOn(otdRepositoryMock, "getAll").and.returnValue(of(jobs));
const getSubscribeSpy = spyOn(otdRepositoryMock.getAll(), "subscribe");
const postSpy = spyOn(otdRepositoryMock, "sendAll").and.returnValue(of(jobs));
const postSubscribeSpy = spyOn(otdRepositoryMock.sendAll([2]), "subscribe");
component.ngOnInit();
//tick();
//flush();
expect(getSpy).toHaveBeenCalled();
expect(getSubscribeSpy).toHaveBeenCalled();
expect(postSpy).toHaveBeenCalled();
expect(postSubscribeSpy).toHaveBeenCalled();
// call ngOnDestroy to unsubscribe
component.ngOnDestroy();
}));
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | djmarquette |
Solution 2 | AliF50 |