Testing Angular interceptors response with Jest and Spectator

1.7k views Asked by At

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.

1

There are 1 answers

3
Ryboflavin On

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'.