[英]Angular - Testing component - Error when returning Promise.reject from mock
我有一個組件單元測試,它沒有以我預期的方式處理模擬的承諾拒絕。
我在一個組件上有這個函數,它發送一些數據到addUserToOrganisation
並處理它返回的Promise:
public onSubmit() {
this.saveStatus = 'Saving';
this.user = this.prepareSaveUser();
this._userService.addUserToOrganisation(this.user)
.then(() => this._router.navigate(['/profile']))
.catch(error => this.reportError(error));
}
在測試這個組件時,我為UserService
提供了一個模擬,它addUserToOrganisation
端點並返回某種Promise:
mockUserService = jasmine.createSpyObj('mockUserService', ['getOrgId', 'addUserToOrganisation']);
mockUserService.getOrgId.and.returnValue(Promise.resolve('an id'));
mockUserService.addUserToOrganisation.and.returnValue(Promise.resolve());
這適用於快樂路徑(解決) - 我可以測試this._router.navigate()
被調用等等。 這是這條快樂路徑的通過測試:
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('j.d@gmail.com');
component.onSubmit();
tick();
fixture.detectChanges();
expect(mockRouter.navigate).toHaveBeenCalledWith(['/profile']);
}));
但是,我在測試“悲傷”的路徑時遇到了麻煩。 我改變我的模擬以返回Promise.reject
,雖然我在onSubmit
有一個.catch
,但是我收到了這個錯誤:
Error: Uncaught (in promise): no
這令人困惑。 這是我對這條悲傷道路的考驗。 請注意,我更改了模擬調用的響應。
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('j.d@gmail.com');
component.onSubmit();
tick();
fixture.detectChanges();
expect(component.saveStatus).toEqual('Failed! no');
}));
有沒有人有任何想法?
承諾拒絕應該被捕獲,如果未處理它們將導致Zone.js承諾實現(在Angular應用程序中使用)和其他一些(Chrome,core-js承諾polyfill等)中的錯誤。
應同步捕獲拒絕以便考慮處理。 這樣可以保證始終處理錯誤。
這是承諾:
const p = Promise.reject();
p.catch(err => console.error(err));
這是未經處理的承諾:
const p = Promise.reject();
setTimeout(() => {
p.catch(err => console.error(err));
}, 1000);
即使將來可能會處理拒絕,但實施方式也無法“知道”這一點,因此承諾被視為未處理,並且unhandledrejection
的拒絕事件被觸發。
造成問題的是
tick();
fixture.detectChanges();
如果tick()
是'以防萬一'並且沒有真正使用它,那么首先它不應該存在。 如果它應該然后代碼需要更改為不創建未處理的承諾:
mockUserService.addUserToOrganisation.and.callFake(() => Promise.reject('no'));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.