Ich habe einen Komponententest, der eine Verheißungsabweisung von einem Schein nicht in der Weise verarbeitet, wie ich es erwartet hatte.Angular - Testing-Komponente - Fehler beim Zurückgeben von Promise.Reject von Mock
Ich habe diese Funktion auf einer Komponente, welche einige Daten zu addUserToOrganisation
und behandelt das Versprechen sendet, dass es zurückgibt:
public onSubmit() {
this.saveStatus = 'Saving';
this.user = this.prepareSaveUser();
this._userService.addUserToOrganisation(this.user)
.then(() => this._router.navigate(['/profile']))
.catch(error => this.reportError(error));
}
wenn diese Komponente zu testen, habe ich eine mock für UserService
zur Verfügung gestellt haben, die auf der addUserToOrganisation
spies Endpunkt und gibt ein Versprechen irgendeiner Art:
mockUserService = jasmine.createSpyObj('mockUserService', ['getOrgId', 'addUserToOrganisation']);
mockUserService.getOrgId.and.returnValue(Promise.resolve('an id'));
mockUserService.addUserToOrganisation.and.returnValue(Promise.resolve());
Dies funktioniert gut für glückliche Pfade (resolve) - ich kann testen, ob this._router.navigate()
genannt wird und so weiter . Hier ist der bestandene Test für diesen glücklichen Weg:
it('should navigate to /profile if save is successful', fakeAsync(() => {
fixture.detectChanges();
tick();
fixture.detectChanges();
component.userForm.controls['firstName'].setValue('John');
component.userForm.controls['lastName'].setValue('Doe');
component.userForm.controls['email'].setValue('[email protected]');
component.onSubmit();
tick();
fixture.detectChanges();
expect(mockRouter.navigate).toHaveBeenCalledWith(['/profile']);
}));
Jedoch habe ich Probleme, den 'traurigen' Weg zu prüfen. Ich ändere meine mock ein Promise.reject
und zurückzukehren, obwohl ich ein .catch
in onSubmit
habe, erhalte ich diese Fehlermeldung:
Error: Uncaught (in promise): no
Also das ist verwirrend. Hier ist mein Test für diesen traurigen Weg. Beachten Sie, dass ich die Antwort des Scheinanrufs ändere.
it('should show Failed save status if the save function fails', fakeAsync(() => {
mockUserService.addUserToOrganisation.and.returnValue(Promise.reject('no'));
fixture.detectChanges();
tick();
fixture.detectChanges();
component.userForm.controls['firstName'].setValue('John');
component.userForm.controls['lastName'].setValue('Doe');
component.userForm.controls['email'].setValue('[email protected]');
component.onSubmit();
tick();
fixture.detectChanges();
expect(component.saveStatus).toEqual('Failed! no');
}));
Hat jemand irgendwelche Ideen?
Ich habe versucht, die 'tick()' zu entfernen und ich habe immer noch einen Fehler. Ich verstehe nicht ganz, wie es unnötig wäre. Allerdings habe ich meine Scheinantwort von 'returnValue ...' auf 'callFake ...' geändert. Ich glaube nicht, dass ich die Nuance hier zu 100% verstehe. – dafyddPrys
'callFake' erstellt eine abgelehnte Zusage in dem Moment, in dem sie aufgerufen wird, so dass sie während des Aufrufs 'component.onSubmit()' mit '.catch' verkettet wird und zu einer Versprechung führt.'returnValue' akzeptiert existierende abgelehnte Versprechen, die sofort mit' .catch' verkettet werden sollten, aber es ist nicht - weil der Timer mit 'tick()' zum nächsten Tick bewegt wird, bevor eine Ablehnung in 'component.onSubmit()' abgefangen wurde. Das Beispiel mit 'setTimeout' zeigt genau, was dort vor sich geht. Es sollte ohne 'tick()' funktionieren. Ich kann nicht sagen, warum du diesen Fehler immer noch ohne ihn bekommst. – estus