How to test polling with rxjs timer?

Emanuele

I have an angular component in which I made a polling in ngOnInit using rjxs timer, like this:

ngOnInit() {
  timer(0, 60000). subscribe(() => {
    this.getSomeStuff();
  }
}

In jest I have a spy on the function:

const getSomeStuff = jest.spyOn( component, 'getSomeStuff' );

My goal is to test how many time the "getSomeStuff" function have been called. For example:

  • after 0 millisecond:

    expect(getSomeStuffSpy).toHaveBeenCalledTimes(1);

should be true.

  • after 60000 milliseconds (a minute):

    expect(getSomeStuffSpy).toHaveBeenCalledTimes(2);

should be true.

But no one works, the expect pass only with 0 and I don't understand why. I tried with fakeAsync anch tick(), I tried with VirtualScheduler and everything I found on other questions, but nothing seems to work with my case.

Anyone have a different approach to try?

Fabian Beyerlein

The problem is, that you probably start the timer in ngOnInit.

If you call fixture.detectChanges() in the beforeEach hook, the timer is already running before you can spy on the function that should be called.

So either you move the timer into a function that you then call in ngOnInit or you have to modify your tests to call fixture.detectChanges() in every test (see below).

Also, you have to call ngOnDestroy or unsubscribe from the timer at the end of every test or you will get an error like 1 periodic timer(s) still in the queue..

So your tests could look like this:

beforeEach(async () => {
  // other setup...

  fixture = TestBed.createComponent(AppComponent);
  component = fixture.componentInstance;

  // don't call fixture.detectChanges() here.
});

it('test 1', fakeAsync(() => {
  const spy = spyOn(component, 'doStuff');

  fixture.detectChanges();

  tick(0);

  expect(spy).toHaveBeenCalledTimes(1);

  component.ngOnDestroy();
}));

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related