4

I'm trying to test an Interceptor that modifies the response from an HTTP Request.

Here's my current code:

@Injectable()
export class ResponseCamelCaseInterceptor implements HttpInterceptor {
  intercept(
    httpRequest: HttpRequest<Record<string, unknown>>,
    httpHandler: HttpHandler,
  ): Observable<HttpEvent<Record<string, unknown>>> {
    return httpHandler.handle(httpRequest).pipe(
      filter(
        (value): value is HttpResponse<Record<string, unknown>> =>
          value instanceof HttpResponse,
      ),
      filter(({ body }) => isPlainObject(body)),
      map(httpEvent =>
        httpEvent.clone({ body: snakeToCamelCase(httpEvent.body) }),
      ),
    );
  }
}

and its corresponding test file I have so far:

describe(ResponseCamelCaseInterceptor.name, () => {
  const createService = createServiceFactory(ResponseCamelCaseInterceptor);

  test('some description', () => {
    const { service } = createService();
    const fakeHttpRequest = new HttpRequest('POST', 'https://...', { custom_key: '1' });

    service.intercept(fakeHttpRequest, 'what should I put here for HttpHandler?').subscribe(() => {
      // expect(httpResponse.body).toStrictEqual({ customKey: '1' });
    });
  });
});

Note that I'm using Angular 10.x.y, Jest 26.x.y and Spectator 5.x.y.

dev_054
  • 3,448
  • 8
  • 29
  • 56

1 Answers1

1

I was able to get the intercept method to take the following. Modify the mockHandler.handle return as needed.

const mockHandler = {
  handle: jest.fn(() =>  of(new HttpResponse({status: 200, body: {data: 'thisIsWhatImTesting'}})))
};


spectator.service.intercept(new HttpRequest<any>(HttpMethod.GET, '/api'), mockHandler)
      .subscribe((response: HttpResponse<any>) => {
        expect(response.body).toStrictEqual({customKey: '1'});
      });

In the subscribe lambda you need to specify the response as input. This should be the processed HttpResponse from the interceptor.

The key here is that to mock in jest you need to use jest.fn() to mock the function. To get TypeScript to recognize the mock as the right class you need to satisfy the interface, by implementing 'handle'.

Ryboflavin
  • 789
  • 5
  • 8
  • Thanks for your answer.. then, I want to pass the body and I'm trying to test if the interceptor "parse" the response correctly. If I pass the response, as you put above, I'm gonna having a circular testing, because I'm passing the response and expecting it at the same time, no? – dev_054 Aug 31 '20 at 21:53
  • @dev_045 I'm not fully sure if I'm following you, but after looking at your code again. It looks like you are trying to test that the interceptor is processing the HttpResponse. Using the mockHandler you are specifying the HttpResponse input of your test. So you could specify the different body condition in the mockHandle, Then in the subscribe of the `spectator.service.intercept().subscribe` you can test the output of the interceptor. I'll update the Answer with a little more detail. – Ryboflavin Sep 01 '20 at 14:53
  • @dev_054 I just update my answer with a more detailed response. I think the confusion is that in the interceptor subscribe lambda you need to specify an input as HttpResponse. This will be the interceptor's processed response. – Ryboflavin Sep 01 '20 at 15:09