茉莉花单元测试的Angular - mock Promise方法

Mar*_*oLe 9 unit-testing mocking jasmine karma-jasmine angular

测试方法

  public onSubmit(registerData: RegisterDataModel): void {
    this.registrationService.registerWithEmailAndPassword(registerData).then((msg: string[]) =>
      this.router.navigate(['/completeSignUp']).then(() => {
        msg.forEach(singleMessage => this.notificationService.primary(singleMessage));
      }))
      .catch((msg) => msg.forEach(singleMessage => {
        this.notificationService.danger(singleMessage);
      }));
  }
Run Code Online (Sandbox Code Playgroud)

我想测试是否router.navigate在我的方法中调用.现在我想嘲笑我的 service.registerWithEmailAndPasswort承诺但不知何故我不能嘲笑它.

我的规范文件

//Stubs
const routerStub: Router = jasmine.createSpyObj('Router', ['navigate']);
const registryStub: RegistrationService = jasmine.createSpyObj('RegistrationService', ['registerWithEmailAndPassword']);
Run Code Online (Sandbox Code Playgroud)

单元测试

  it('should navigate on promise - success', () => {
    (<jasmine.Spy>registryStub.registerWithEmailAndPassword).and.callThrough();
    const spy = (<jasmine.Spy>routerStub.navigate);
    component.onSubmit({username: null, email: null, password: null, passwordConfirm: null, termsAndCondition: null});
    expect(spy).toHaveBeenCalledWith(['/completeSignUp']);
  });
Run Code Online (Sandbox Code Playgroud)

出现的错误是:TypeError: Cannot read property 'then' of undefined 有人如何正确模拟此服务?

编辑

我也试图模仿这样的承诺:

    (<jasmine.Spy>registryStub.registerWithEmailAndPassword)
  .and.returnValue(new Promise(() => Promise.resolve()));
Run Code Online (Sandbox Code Playgroud)

但它仍然让我感到:

Expected spy Router.navigate to have been called with [ [ '/completeSignUp' ] ] but it was never called.
Run Code Online (Sandbox Code Playgroud)

小智 8

正如硅魂所提到的那样,你需要router.navigate用一个返回值来嘲笑这个诺言,否则它就会变成一个Promise.reject().通过添加(<jasmine.Spy>routerStub.navigate).and.returnValue(Promise.resolve());单元测试应该没问题.最终的单元测试应如下所示:

  it('should navigate on promise - success', fakeAsync(() => {
    const spy = (<jasmine.Spy>routerStub.navigate).and.returnValue(Promise.resolve());
    (<jasmine.Spy>registryStub.registerWithEmailAndPassword).and.returnValue(Promise.resolve(['test']));
    component.onSubmit({username: 'test', email: 'test', password: 'test', passwordConfirm: 'test', termsAndCondition: true});

    tick();
    expect(spy).toHaveBeenCalledWith(['/completeSignUp']);
  }));
Run Code Online (Sandbox Code Playgroud)