Search code examples
angularrxjsts-mockito

How can i supress Api error and return a value instead?


I get a 404 for unused and a 204 for used email from my API. Now i want to transform that to boolean (true/false) using rxjs/pipe and catchError.

emailAvailable(): Observable<boolean> {
  return this.api.email(email).pipe(
    map((response: HttpResponse<any>) => {
      return false; // used email > false
    }),
    catchError((err: HttpErrorResponse) => {
      if (err.status === 404) {
        return of(true); // unused > true
      }
      throw err;
    })
  );
}

Now in my unit test i have the case for an unused e-mail defined like this

when(mockApi.email('[email protected]')).thenThrow(
  new HttpErrorResponse({status: 404, statusText: 'E-Mail not in use', error: { message: 'E-Mail not in use'}}));

And then it try to write my test like this.

it('should validate for unused email', async() => {
    expect(await readFirst(emailService.emailAvailable('[email protected]'))).toBe(true);
});

Now the test fails because an HttpErrorResponse is thrown:

 ● EmailValidator › should validate form for unused email
    HttpErrorResponse: Http failure response for (unknown url): 404 E-Mail not in use

So the Observable throws the error i thought i catched with catchError. My test setup is jest, i do not want to (nor can i) switch to TestBed.


Solution

  • What helped me is this Post:

    Angular 7 - catching HttpErrorResponse in unit tests

    the "throw error" path should return the error inside an "of" so it gets testable also.

    the mock can end up like this:

    when(mockApi.email('[email protected]')).thenReturn(
      throwError(new HttpErrorResponse(
        { status: 404, statusText: 'E-Mail not in use', error: { message: 'E-Mail not in use'} } 
    )));
    

    And in that Test you can check for your value or that error message