web-dev-qa-db-fra.com

Angular 2 Test - Appel de fonction asynchrone - Quand utiliser

Quand utilisez-vous la fonction asynchrone dans le TestBed lorsque vous testez dans Angular 2?

Quand utilisez-vous cela?

 beforeEach(() => {
        TestBed.configureTestingModule({
            declarations: [MyModule],
            schemas: [NO_ERRORS_SCHEMA],
        });
    });

Et quand utilisez-vous cela?

beforeEach(async(() => {
    TestBed.configureTestingModule({
        declarations: [MyModule],
        schemas: [NO_ERRORS_SCHEMA],
    });
}));

Est-ce que quelqu'un peut m'éclairer à ce sujet ?

66
xiotee

async n'autorisera pas le prochain test avant que async n'ait terminé toutes ses tâches. Qu'est-ce que async enrobe le rappel dans une zone, où toutes les tâches asynchrones (par exemple, setTimeout) sont suivies. Une fois que toutes les tâches asynchrones sont terminées, le async est terminé.

Si vous avez déjà travaillé avec Jasmine en dehors de Angular, vous avez peut-être vu done être transmis au rappel

it('..', function(done) {
  someAsyncAction().then(() => {
    expect(something).toBe(something);
    done();
  });
});

Ici, il s'agit de Jasmin natif, où nous disons à Jasmine que ce test devrait retarder l'achèvement jusqu'à ce que nous appelions done(). Si nous n'avons pas appelé done() et que nous avons plutôt fait ceci:

it('..', function() {
  someAsyncAction().then(() => {
    expect(something).toBe(something);
  });
});

Le test s'achèverait même avant la date prévue, car la promesse est résolue après le test est terminé pour l'exécution des tâches synchrones.

Avec Angular (dans un environnement Jasmine), Angular appellera en réalité done en arrière-plan lorsque nous utilisons async. Il gardera une trace de toutes les tâches asynchrones dans la Zone et quand elles seront toutes terminées, done sera appelé en coulisse.

Dans votre cas particulier avec la configuration TestBed, vous l'utiliserez généralement lorsque vous voulez utiliser compileComponents. Je rencontre rarement une situation dans laquelle je devrais l'appeler autrement

beforeEach(async(() => {
   TestBed.configureTestingModule({
     declarations: [MyModule],
     schemas: [NO_ERRORS_SCHEMA],
   })
   .compileComponent().then(() => {
      fixture = TestBed.createComponent(TestComponent);
   });
}));

Lors du test d'un composant qui utilise templateUrl (si vous n'utilisez pas webpack), alors Angular doit faire une demande XHR pour obtenir le modèle, de sorte que la compilation du composant être asynchrone. Nous devons donc attendre que le problème soit résolu avant de poursuivre les tests.

75
Paul Samsotha

Lorsque vous effectuez un appel asynchrone dans votre test, la fonction de test est terminée avant l'appel asynchrone. Lorsque vous devez vérifier l'état de la fin de l'appel (ce qui est généralement le cas), le cadre de test indique alors que le test est terminé tant qu'un travail asynchrone est en cours.

Avec async(...), vous indiquez au framework de test d'attendre que la promesse de retour ou l'observable soit terminé avant de traiter le test comme terminé.

it('should show quote after getQuote promise (async)', async(() => {
  fixture.detectChanges();

  fixture.whenStable().then(() => { // wait for async getQuote
    fixture.detectChanges();        // update view with quote
    expect(el.textContent).toBe(testQuote);
  });
}));

Le code transmis à then(...) sera exécuté après la fonction de test elle-même terminée. Avec async(), vous indiquez au framework de test qu'il doit attendre que les promesses et les observables soient terminés avant de traiter le test comme terminé.

Voir également

22
Günter Zöchbauer