How to Test a Functional Interceptor in Angular
Tags: angular, providehttpclienttes, interceptors, unittesting
Published: 2023-10-04 00:08:27

---
title: How to Test a Functional Interceptor in Angular
published: true
date: 2023-10-03 21:24:20 UTC
tags: angular,providehttpclienttes,interceptors,unittesting
canonical_url: https://medium.com/@seanhaddock_60973/how-to-test-a-functional-interceptor-in-angular-6c8095c1fb7d
---

![](https://cdn-images-1.medium.com/max/1024/0*9sz3FqKaTK_DsTxb)
_Photo by Ben Mullins on Unsplash_

This post will build upon my previous [one](https://dev.to/seanbh/how-to-create-a-functional-interceptor-in-angular-2kjp-temp-slug-3756378) and show you how to test the functional interceptor that was implemented there:

```
import {
  HttpRequest,
  HttpInterceptorFn,
  HttpHandlerFn,
  HttpEvent,
} from '@angular/common/http';
import { Observable } from 'rxjs';

export const authInterceptor: HttpInterceptorFn = (
  request: HttpRequest<unknown>,
  next: HttpHandlerFn
): Observable<HttpEvent<unknown>> => {
  const clonedRequest = request.clone({
    setHeaders: {
      Authorization: 'Bearer [the token]',
    },
  });
  return next(clonedRequest);
};
```

I am going to compare and contrast testing class-based and functional interceptors in this post, but feel free to skip straight to the functional interceptor test if that is all you are interested in.

### Class-Based Test

A simple class-based test might look like this:

```
import { TestBed } from '@angular/core/testing';
import {
  HttpClientTestingModule,
  HttpTestingController,
} from '@angular/common/http/testing';
import { AuthInterceptor } from './auth.interceptor';
import { HTTP_INTERCEPTORS, HttpClient } from '@angular/common/http';

describe('AuthInterceptor', () => {
  let httpTestingController: HttpTestingController;
  let httpClient: HttpClient;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule],
      providers: [
        AuthInterceptor,
        { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
      ],
    });
    httpTestingController = TestBed.inject(HttpTestingController);
    httpClient = TestBed.inject(HttpClient);
  });
  
  afterEach(() => {
    httpTestingController.verify();
  });

  it('should add auth headers ', () => {
    //arrange
    const url = '/mockendpoint';

    //act
    httpClient.get(url).subscribe();

    // assert
    const req = httpTestingController.expectOne(url);
    expect(req.request.headers.get('Authorization')).toEqual(
      'Bearer [the token]'
    );
  });
});
```

There is a fair bit of code here and I’ve gone over the details in a previous [post](https://dev.to/seanbh/how-to-unit-test-an-httpinterceptor-that-relies-on-ngrx-33pi) and won’t repeat them here. The test itself is just making a (fake) HTTP request and then checking the header to verify that the token was added. It is the same regardless of whether the interceptor is class-based or functional. What does change is how we _provide_ the interceptor.

### Functional Test

Just like we did in the previous [post](https://dev.to/seanbh/how-to-create-a-functional-interceptor-in-angular-2kjp-temp-slug-3756378), we need to switch to providing HttpClient using the standalone API, and then we can provide authInterceptor at the same time:

```
// removed the imports[]

providers: [
  provideHttpClient(withInterceptors([authInterceptor])),
  provideHttpClientTesting(),
],
```

Notice that we have also included the provideHttpClientTesting function call and removed the imports array that contained HttpClientTestingModule.

Remember, the shift to standalone includes replacing modules with function calls. Just like provideHttpClient replaced importing the HttpClientModule, provideHttpClientTesting replaces importing the HttpClientTestingModule.

Here’s the diff between the class-based and functional test:

![](https://cdn-images-1.medium.com/max/1024/1*XrLy9zb4YyfHBsms_wgzUw.png)
_The code difference between the class-based and functional tests_

Here is the test in full:

```
import { TestBed } from '@angular/core/testing';
import {
  HttpTestingController,
  provideHttpClientTesting,
} from '@angular/common/http/testing';
import {
  HttpClient,
  provideHttpClient,
  withInterceptors,
} from '@angular/common/http';
import { authInterceptor } from './auth.interceptor';

describe('AuthInterceptor', () => {
  let httpTestingController: HttpTestingController;
  let httpClient: HttpClient;

  beforeEach(() => {
    TestBed.configureTestingModule({
      // here are the KEY changes
      providers: [
        provideHttpClient(withInterceptors([authInterceptor])),
        provideHttpClientTesting(),
      ],
    });
    httpTestingController = TestBed.inject(HttpTestingController);
    httpClient = TestBed.inject(HttpClient);
  });

  afterEach(() => {
    httpTestingController.verify();
  });

  it('should add auth headers ', () => {
    //arrange
    const url = '/mockendpoint';

    //act
    httpClient.get(url).subscribe();

    // assert
    const req = httpTestingController.expectOne(url);
    expect(req.request.headers.get('Authorization')).toEqual(
      'Bearer [the token]'
    );
  });
});
```

That’s it! I hope you found this useful.

### Bibliography

- [Angular — provideHttpClient](https://angular.io/api/common/http/provideHttpClient)
- [Angular — withInterceptors](https://angular.io/api/common/http/withInterceptors)
- [Angular — provideHttpClientTesting](https://angular.io/api/common/http/testing/provideHttpClientTesting)