NagRock / ts-mockito

Mocking library for TypeScript
MIT License
969 stars 93 forks source link

How to mock catchError #227

Open ascdi opened 2 years ago

ascdi commented 2 years ago

i am trying to test a path that leads into an rxjs catchError function.

Example Code:

    return next.handle(request).pipe(
      catchError((error: HttpErrorResponse) => {
        console.log(`test`);

Now i am Mocking the next Part using mock & instance and tried both thenThrow and thenReturn(throwError( in Order to throw an error that could be catched by catchError. But i never reach the console.log statement.

Example:

    when(mockHttpHandler.handle(anything())).thenReturn(
      throwError(
        new HttpErrorResponse({
          error: 'some cryptic error called 93457tz9w345hzg9w24phg9ow4jh',
          url: testUrl,
          status: 500,
        })
      )
    );

How can i reach that path, mocking my next.handle?

DKozachenko commented 2 months ago

I suppose, I had the same problem. I have a simple http service, that has method getHeroes. If request is successfull, it returns array with objects. If request failed, it returns empty array. The code of this method is:

getHeroes(): Observable<Hero[]> {
    return this.http.get<Hero[]>(this.heroesUrl).pipe(catchError(() => of([])));
}

The code of test case for situation, when request failed is:

it('should return empty array via "getHeroes" method if request has failed', () => {
    const mockError = new HttpErrorResponse({
      url: 'api/heroes',
      status: 500,
      statusText: 'server error',
    });
    when(mockHttp.get('api/heroes')).thenReturn(throwError(() => mockError));
    const service = createService();

    expect(service.getHeroes()).toBeObservable(
      cold('(a|)', {
        a: [],
      })
    );
});

As you can see I used throwError operator, also I added a | symbol of marble syntax to test has passed. I'm not sure, it's a best way to solve the problem, but it's ONLY option (I tried a lots of variants over 1,5-2 hours!).