2

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

2 Answers 2

8

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,

Sign up to request clarification or add additional context in comments.

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.