繁体   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