U gebruikt een verouderde browser. Upgrade uw browser om deze site correct weer te geven.

How to Test Angular Response Interceptors


Need to test a HTTP request interceptor? We've got you covered.

If you want to read more about interceptors, and how they can be used to keep your domain models clean, look no further.


As we have seen in a previous post, angular interceptors are a useful tool to convert outbound requests and incoming responses. They are a great way to keep your application clean while bridging the gap with any API.

Because your interceptors play a crucial role in your application, they should be unit tested. Luckily, this is easy to do once you know the trick.

To see this in action, we'll use a response interceptor that converts from snake_case to camelCase. It's a common requirement in applications that need to talk to a Python backend.

Here's the interceptor:

camelify.interceptor.ts
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// ... omitted other imports for brevity
import { camelCase, mapKeys } from 'lodash-es'

@Injectable()
export class CamelifyInterceptor implements HttpInterceptor {

  intercept(request: HttpRequest<unknown>, next: HttpHandler):
    Observable<HttpEvent<unknown>> {
    return next.handle(request).pipe(
      map(value => this.handleResponse(value))
    )
  }

  private handleResponse(response: HttpResponse<unknown>) {
    if (response.ok && response.body) {
      // this is just a simple example
      // in reality you probably want a recursive function
      // to deal with nested objects and collections
      const body = mapKeys(response.body, camelCase)
      return response.clone({ body })
    }

    return response
  }
}

How should we bring this code under test? One approach is to instantiate the interceptor as a class and call the intercept method with a mock request and handler. But mocking the request and next handler isn't quite as straightforward as we'd like.

The preferred approach is to register the interceptor and test it using the HttpClientTestingModule. It sounds and feels a little like an integration test, but it's really easy to set up and use. Watch.

camelify.interceptor.spec.ts
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
describe('CamelifyInterceptor', () => {
  let client: HttpClient
  let controller: HttpTestingController

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [
        HttpClientTestingModule,
      ],
      providers: [
        // register our interceptor with the testing module
        {
          provide: HTTP_INTERCEPTORS,
          useClass: CamelifyInterceptor,
          multi: true
        }
      ],
    })

    client = TestBed.inject(HttpClient)
    controller = TestBed.inject(HttpTestingController)
  })

  it('should convert object keys to camelCase', (done) => {
    const body = { camel_case: true }
    const expected = { camelCase: true }

    client.get('/test').subscribe(response => {
      expect(response).toEqual(expected)
      // if you're using Jest, you must use the done() callback
      // or the test will simply time out
      done()
    })

    const request = controller.expectOne('/test')
    request.flush(body) // 'resolves' the request, triggering our assertion
  })
})

In the setup function of the test suite we register our interceptor with the testing module, and import the HttpClientTestingModule. During our test we'll need access to the HttpClient and the HttpTestingController (both imported from the HttpClientTestingModule).

In the unit test itself we start by defining a response body that our backend supposedly returns and the expected result after that response has been intercepted. Next, we create a GET request from the HttpClient and subscribe to it. When the request completes the assertion is triggered.

So all we need to do now is make sure the request triggers a response. We do that by getting the request from the controller, and then using the flush method to resolve the request with the desired response body.

The assertion we placed after the get call will now get the response body, and it will find that it the response has been magically altered by our interceptor.

And that's it! Now go forth and test those interceptors :)


We gebruiken cookies en vergelijkbare technologieën om de gebruikerservaring te verbeteren en om content te leveren die relevant is voor onze doelgroepen. Afhankelijk van hun doel, kunnen analyse- en marketingcookies worden gebruikt naast technisch noodzakelijke cookies. Door op "Akkoord" te klikken, verklaart u akkoord te gaan met het gebruik van bovengenoemde cookies.