Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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. Now I want to mock my service.registerWithEmailAndPasswort Promise but somehow I cannot mock it.

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?

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.
like image 967
MarcoLe Avatar asked Jul 27 '18 14:07

MarcoLe


1 Answers

You will get the error because the registerWithEmailAndPassword spy does not return a Promise. You could use callFake to return a 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.

like image 56
SiliconSoul Avatar answered Oct 07 '22 04:10

SiliconSoul