简体   繁体   English

Angular - Jasmine 单元测试的模拟 Promise 方法

[英]Angular - mock Promise method for Jasmine unit test

Method to test测试方法

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

I want to test if router.navigate is called in my method.我想测试是否在我的方法中调用了router.navigate Now I want to mock my service.registerWithEmailAndPasswort Promise but somehow I cannot mock it.现在我想模拟我的service.registerWithEmailAndPasswort Promise 但不知何故我无法模拟它。

My Spec File我的规格文件

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

Unit test单元测试

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

The Error that is appearing is: TypeError: Cannot read property 'then' of undefined Does anyone how to proper mock this service?出现的错误是: TypeError: Cannot read property 'then' of undefined人如何正确模拟此服务?

Edit编辑

I have also tried to mock the promise like:我也试图嘲笑这样的承诺:

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

But it still throws me:但它仍然让我觉得:

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

As silicon Soul mentioned you need definately mock the router.navigate promise with a returnvalue as otherwise it will ent into a Promise.reject() .正如硅灵魂所提到的,您肯定需要使用返回值模拟router.navigate承诺,否则它将进入Promise.reject() By adding (<jasmine.Spy>routerStub.navigate).and.returnValue(Promise.resolve());通过添加(<jasmine.Spy>routerStub.navigate).and.returnValue(Promise.resolve()); the unit test should be ok.单元测试应该没问题。 The final unit test should look like:最终的单元测试应如下所示:

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

You will get the error because the registerWithEmailAndPassword spy does not return a Promise.您将收到错误消息,因为 registerWithEmailAndPassword 间谍不返回 Promise。 You could use callFake to return a Promise:您可以使用 callFake 返回一个 Promise:

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

Also, promises are asynchronous so you should probably use fakeAsync test and tick, or timeout or return an object with then method instead of a Promise.此外,promise 是异步的,因此您可能应该使用fakeAsync测试和滴答,或超时或使用then方法而不是 Promise 返回对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM