web-dev-qa-db-fra.com

Angular 2 fakeAsync en attente de timeout dans une fonction utilisant tick ()?

J'essaie d'obtenir les résultats d'un backend simulé dans Angular 2 pour les tests unitaires. Nous utilisons actuellement fakeAsync avec un délai d'expiration pour simuler le passage du temps. 

test unitaire de travail actuel

it('timeout (fakeAsync/tick)', fakeAsync(() => {
    counter.getTimeout();
    tick(3000); //manually specify the waiting time
}));

Mais cela signifie que nous sommes limités à un délai d'attente défini manuellement. Pas lorsque la tâche asynchrone est terminée. Ce que j'essaie de faire, c'est que tick() attende que la tâche soit terminée avant de poursuivre le test. 

Cela ne semble pas fonctionner comme prévu. 

En lisant sur fakeAsync et tick la réponse ici explique que 

tick () simule le passage du temps asynchrone.

J'ai mis en place un exemple de plnkr simulant ce scénario. 

Ici, nous appelons la méthode getTimeout() qui appelle une tâche asynchrone interne dont le délai est dépassé. Lors du test, nous essayons de l'encapsuler et d'appeler tick() après avoir appelé la méthode getTimeout()

counter.ts

getTimeout() {
  setTimeout(() => {
    console.log('timeout')
  },3000)
}

counter.specs.ts

it('timeout (fakeAsync/tick)', fakeAsync(() => {
    counter.getTimeout();
    tick();
}));

Mais le test unitaire échoue avec l'erreur "Erreur: 1 minuterie (s) toujours dans la file d'attente".

Est-ce que le problème dans le repo angulaire a quelque chose à voir avec cela?

Est-il possible d'utiliser tick() de cette façon pour attendre une fonction de délai d'attente? Ou y a-t-il une autre approche que je peux utiliser? 

6
nipuna777

Essaye ça:

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

La source

1
SrAxi

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],
    });
  });

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

Faux 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],
    });
  });

  it("timeout test", fakeAsync(() => {
    service.getTimeout();
    tick(service.WAIT_TIME + 10);
  });
});
0
christo8989

A la fin de chaque test, ajoutez:

 fixture.destroy();
 flush();
0
dangchithao

J'utilise normalement la méthode flushMicrotasks dans mes tests unitaires pour une utilisation avec mes services. J'avais lu que tick () est très similaire à flushMicrotasks mais appelle également la méthode jasmine tick (). 

0
Nick