Angular 7: Test Error Interceptor

Testing an error interceptor can be a little tricky. Below is the code I want to test :

import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HttpErrorResponse } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { AuthenticationService } from './../services/authentication.service';
@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
constructor(private authenticationService: AuthenticationService) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request).pipe(catchError((err: HttpErrorResponse) => {
if (err.error instanceof ErrorEvent) {
//TODO : add server log for client errors
} else {
if ([401, 403].indexOf(err.status) !== -1) {
// automatically logout
this.authenticationService.logout();
}
}
const error = err.error || err.statusText;
return throwError(error);
}))
}
}


Basically we need to perform an HTTP request and respond with a mocking error for testing this interceptor. You need also to register it in the TestBed.configureTestingModule.

import { TestBed } from '@angular/core/testing';
import {
HttpClientTestingModule,
HttpTestingController
} from '@angular/common/http/testing';
import { HTTP_INTERCEPTORS, HttpClient, HttpErrorResponse } from '@angular/common/http';
import { ErrorInterceptor } from './error.interceptor';
import { AuthenticationService } from '../services/authentication.service';
import { MockAuthService } from './../../testing/services/authentication.service.mock';
const testUrl = '/data';
interface Data {
name: string;
}
describe('ErrorInterceptor', () => {
describe('intercept', () => {
let errorInterceptor: ErrorInterceptor;
let authService: AuthenticationService;
let httpClient: HttpClient;
let httpMock: HttpTestingController;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [ErrorInterceptor,
{ provide: AuthenticationService, useClass: MockAuthService },
{
provide: HTTP_INTERCEPTORS,
useClass: ErrorInterceptor,
multi: true,
}
],
imports: [HttpClientTestingModule]
});
httpClient = TestBed.get(HttpClient);
httpMock = TestBed.get(HttpTestingController);
authService = TestBed.get(AuthenticationService);
spyOn(authService, 'logout');
errorInterceptor = TestBed.get(ErrorInterceptor);
});
it('When 401 or 403, user is automatically logged out and error is rethrow', () => {
const emsg = 'deliberate 401 error';
// Make an HTTP GET request
httpClient.get<Data>(testUrl).subscribe(
res => fail('should have failed with the 401 error'),
(error: HttpErrorResponse) => {
expect(error).toEqual(emsg, 'message');
}
);
// The following `expectOne()` will match the request's URL.
const req = httpMock.expectOne(testUrl)
// Respond with mock error
req.flush(emsg, { status: 401, statusText: 'Unauthorized' });
expect(authService.logout).toHaveBeenCalledTimes(1);
});
});
});


Thanks for sharing...

Comments

Popular posts from this blog

Spring JPA : Using Specification with Projection

Chip input using Reactive Form