mardi 4 décembre 2018

Angular 7 - catching HttpErrorResponse in unit tests

i'm currently learning Angular 7 (haven't used any previous version) and encountered something i couldn't fix when writing unit tests for a service.

I have a service that gets JSON from REST and parses it into a Class. Referring to the Angular Docs, i wrote a test using HttpClientSpy to simulate a 404 Error.

What happens: The Test Fails with the Error Message: "expected data.forEach is not a function to contain '404'"

So the Service gets the HttpErrorResponse as Input but tries to parse it like it was a regular response in the map function. This fails, catchError is called and the data.forEach is not a function Error is thrown.

Expected behavior: i would expect that map() is not executed and it should jump directly into the catchError function.

How i fixed it (for now): Adding the following lines of code to the map function of the service makes the test work.

if (data instanceof HttpErrorResponse)
      throw new HttpErrorResponse(data);

The test:

it('should throw an error when 404', () => {

const errorResponse = new HttpErrorResponse({
  error: '404 error',
  status: 404, statusText: 'Not Found'
});

httpClientSpy.get.and.returnValue(of(errorResponse));

service.getComments().subscribe(
  fail,
  error => expect(error.message).toContain('404')
);
});

The service:

getComments(): Observable<CommentList> {
return this.http
.get('https://jsonplaceholder.typicode.com/comments')
.pipe(
  map((data: Array<any>) => {
    let t: Array<Comment> = [];

    data.forEach(comment => {

      if(!('id' in comment) || !('body' in comment) || !('email' in comment) || !('name' in comment))
        throw new Error("Could not cast Object returned from REST into comment");

      t.push(<Comment>{
        id: comment.id,
        body: comment.body,
        author: comment.email,
        title: comment.name,
      });

    });
    return new CommentList(t);
  }),
  catchError((err: HttpErrorResponse) => {
    return throwError(err);
  })
);
}

Am i getting something wrong? I think the expected behavior is what i should experience, at least thats how i interpret the Angular docs.

Aucun commentaire:

Enregistrer un commentaire