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

时间:2018-07-27 14:42:40

标签: angular unit-testing jasmine mocking karma-jasmine

测试方法

  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);
      }));
  }

我想测试是否在我的方法中调用了router.navigate。现在,我想嘲笑我的service.registerWithEmailAndPasswort诺言,但以某种方式我无法嘲笑它。

我的规格文件

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

单元测试

  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']);
  });

出现的错误是:TypeError: Cannot read property 'then' of undefined 有人会嘲笑这项服务吗?

编辑

我也曾试图嘲笑诺言,

    (<jasmine.Spy>registryStub.registerWithEmailAndPassword)
  .and.returnValue(new Promise(() => Promise.resolve()));

但是它仍然让我失望:

Expected spy Router.navigate to have been called with [ [ '/completeSignUp' ] ] but it was never called.

2 个答案:

答案 0 :(得分:6)

正如Silicon Soul所述,您必须使用返回值来模拟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']);
  }));

答案 1 :(得分:1)

您将收到错误消息,因为registerWithEmailAndPassword间谍未返回Promise。您可以使用callFake返回Promise:

(<jasmine.Spy>registryStub.registerWithEmailAndPassword).and.callFake(() => Promise.resolve([]));

此外,promise是异步的,因此您可能应该使用fakeAsync测试和滴答,超时或使用 then 方法而不是Promise返回对象。