Angular 2 fakeAsync waiting for timeout in a function using tick()?

隐身守侯 提交于 2019-12-04 00:30:00

The purpose of fakeAsync is to control time within your spec. tick will not wait for any time as it is a synchronous function used to simulate the passage of time. If you want to wait until the asynchronous function is complete, you are going to need to use async and whenStable, however, in your example, the spec will take 3 seconds to pass so I wouldn't advise this.

The reason why the counter.spec.ts is failing is that you have only simulated the passage of 0 seconds (typically used to represent the next tick of the event loop). So when the spec completes, there are still mocked timers active and that fails the whole spec. It is actually working properly by informing you that a timeout has been mocked an is unhandled.

Basically, I think you are attempting to use fakeAsync and tick in ways for which they were not intended to be used. If you need to test a timeout the way that you have proposed, the simplest way would be to mock the setTimeout function yourself so that, regardless of the time used, you can just call the method.

EDITED I ran into a related issue where I wanted to clear the timers, and since it was not the part under test, I didn't care how long it took. I tried:

tick(Infinity);

Which worked, but was super hacky. I ended up going with

discardPeriodicTasks();

And all of my timers were cleared.

At the end of each test add:

 fixture.destroy();
 flush();
SrAxi

Try this:

// I had to do this:
it('timeout (fakeAsync/tick)', (done) => {
  fixture.whenStable().then(() => {
       counter.getTimeout();
       tick();
    done();
  });
});

Source

I normally use the flushMicrotasks method in my unit tests for use with my services. I had read that tick() is very similar to flushMicrotasks but also calls the jasmine tick() method.

Async

test.service.ts

export class TestService {
  getTimeout() {
    setTimeout(() => { console.log("test") }, 3000);
  }
}

test.service.spec.ts

import { TestBed, async } from '@angular/core/testing';

describe("TestService", () => {
  let service: TestService;

  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [TestService],
    });

    service = TestBed.get(TestService);
  });

  it("timeout test", async(() => {
    service.getTimeout();
  });
});

Fake Async

test.service.ts

export class TestService {
  readonly WAIT_TIME = 3000;

  getTimeout() {
    setTimeout(() => { console.log("test") }, this.WAIT_TIME);
  }
}

test.service.spec.ts

import { TestBed, fakeAsync } from '@angular/core/testing';

describe("TestService", () => {
  let service: TestService;

  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [TestService],
    });

    service = TestBed.get(TestService);
  });

  it("timeout test", fakeAsync(() => {
    service.getTimeout();
    tick(service.WAIT_TIME + 10);
  });
});
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!