Home > Mobile >  How to properly test statements in setInterval() in Angular?
How to properly test statements in setInterval() in Angular?

Time:01-19

I have this very simple code:

public async authenticate(username: string, password: string) {
    const authenticationResponse = await this.dataProvider.authenticate(username, password);

    if (authenticationResponse.result.code == 0) {
        //start interval for periodically checking authentication info
        this._authInfoIntervalId = setInterval(() => {
             this.getAuthInfo();
        }, 2000);

In my unit tests only line with this.getAuthInfo() is not concidered as covered. Is it somehow possible to test this? I have tried some approaches with jasmine.createSpy but nothing seemed to work (most likely because I was doing it wrong). Can someone please help me to get it right? Thanks

UPDATE: I tried something like this

it('should test interval somehow', () => {
  const intervalCallback = jasmine.createSpy("getAuthInfo");
  jasmine.clock().install();
  service.authenticate('username', 'password');
  jasmine.clock().tick(2001);
  expect(intervalCallback).toHaveBeenCalled();
})

and test fails instantly with AuthenticationService should test interval somehow FAILED Expected spy getAuthInfo to have been called.

SOLUTION: I had to spyOn also on dataProvider so I got right response to actually reach that part of code with interval

  it('should test interval somehow', async () => {
    const intervalCallback = spyOn(service, 'getAuthInfo');
    spyOn(dataProvider, 'authenticate').and.returnValue(Promise.resolve(authenticateMockResponse));
    jasmine.clock().install();
    await service.authenticate('username', 'password');
    jasmine.clock().tick(2001);
    expect(intervalCallback).toHaveBeenCalled();
  });

CodePudding user response:

jasmine.createSpy() should be used for creating a bare spy object, see the documentation. It doesn't have any connection to your service, it's not what you are looking for.

You want to spy a function on an existing object (in your case the service), for which you can use the spyOn function.

it('should test interval somehow', () => {
  const intervalCallback = spyOn(service, 'getAuthInfo');
  jasmine.clock().install();
  service.authenticate('username', 'password');
  jasmine.clock().tick(2001);
  expect(intervalCallback).toHaveBeenCalled();
})

CodePudding user response:

In Angular, you can use the async and fakeAsync functions from the @angular/core/testing module to properly test statements within a setInterval() function.

First, you'll need to wrap your test in the fakeAsync function, which allows you to use the tick() function to advance the virtual time. Next, you'll need to wrap the code you want to test within the setInterval() function in an async function.

  • Related