2017-12-19 4 views
1

ich, dass die promse Funktion in der folgenden FunktionAngular Jamine/Karma Test Versprechen Funktion

loadDetail(id) { 
    this.bookingService.getServices(id).then((ret) => { 
     if (ret.result) { 
      this.sevices = ret.payload; 
     } 
    }).catch((error) => {});  
} 

Mein Test ist zu prüfen, bin versucht:

it('loadDetail successfully return services.', inject(
    [BookingService], (service: BookingService) => { 
     service.initBooking(); 

     let ret = new returnObj(); 
     ret.result = true; 
     ret.payload = new Array<any>(); 
     ret.payload.push({id: 1, title: "Title 1"}); 
     ret.payload.push({id: 2, title: "Title 2"}); 
     ret.payload.push({id: 3, title: "Title 3"}); 

     const spy = spyOn(service, "getServices").and.returnValue(Promise.resolve(ret)); 

     component.loadDetail(1); 

     expect(component.sevices.length).toEqual(3); 
    } 
)); 

Wenn ich den Test ausführen, ich der Fehler "Erwartete 0 bis gleich 3" Was mache ich hier falsch? Ich habe Beispiele verfolgt und bin mir ziemlich sicher, dass ich den Spion richtig benutze.

Antwort

1

Das Problem ist, dass Versprechungen asynchron sind, und das Ergebnis wird bestätigt, bevor loadDetail(1) abgeschlossen wurde.

Um effizient getestet zu werden, sollte asynchrone Funktion immer ein Versprechen oder eine beobachtbare zurück:

loadDetail(id) { 
    return this.bookingService.getServices(id).... 
} 

Wenn es nicht soll ein Ergebnis zurückkehrt, wird es ein Versprechen von undefined sein.

So kann es verkettet werden. Dies ist besonders hilfreich bei async..await und async oder fakeAsync Angular Helfer:

it('loadDetail successfully return services.', fakeAsync(inject(
    [BookingService], async (service: BookingService) => { 
     ... 
     const spy = spyOn(service, "getServices").and.returnValue(Promise.resolve(ret)); 

     await component.loadDetail(1); 

     expect(component.sevices.length).toEqual(3); 
    } 
)); 

Dies kann auch mit fakeAsync und tick Helfer gelöst werden asynchronen Code in synchroner Weise zu testen (dies wird nicht mit wirklich asynchronen Operationen wie echte HTTP arbeiten Anfragen):

it('loadDetail successfully return services.', fakeAsync(inject(
    [BookingService], (service: BookingService) => { 
     ... 
     const spy = spyOn(service, "getServices").and.returnValue(Promise.resolve(ret)); 

     component.loadDetail(1); 
     tick(0); // promise chain was executed 

     expect(component.sevices.length).toEqual(3); 
    } 
));