簡體   English   中英

Angular - 測試組件 - 從mock返回Promise.reject時出錯

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM