Can you tell me how to test the HttpInterceptor provided by the Angular 4. I have created an interceptor as per the examples but not sure how to test it. Below is my interce
I'm a bit late to the post, but I figured out a way of testing the interceptors outside of Angular's context. This means that you don't have to mock HTTP calls, you only test the intercept function like any Javascript function.
Let's say your interceptor only does that, which is displaying a log if the error status is 500 :
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next
.handle(req)
.catch((err: HttpErrorResponse) => {
if(err.status === 500) { console.log('Server error'); }
});
}
Then, in your service, you can mock the parameters of your function like so :
const err: any = { status: 500 };
const next: any = {
handle: (request: HttpRequest<any>) => ({
catch: (callback: Function) => callback(err)
})
};
With that, you can write a test for your interceptor :
it('should write a console log with error status equal to 500', () => {
spyOn(console, 'log');
service.intercept({} as any, next);
expect(console.log).toHaveBeenCalled();
});
And voilà !
I wanted to get the response from the request modified by the interceptor, so I used the callback method of the handle object.
Test:
it("should set header authorization", async(() => {
const token: string = "token_value";
let response: HttpResponse<any>;
const next: any = {
handle: responseHandle => {
response = responseHandle;
}
};
const request: HttpRequest<any> = new HttpRequest<any>("GET", `${API_URL}`);
tokenInterceptor.intercept(request, next);
expect(response.headers.get("Authorization")).toEqual(token);
}));
I also used a service mock that generates the token to control the value I wanted to validate.
I got stuck testing a similar thing, but thanks to Alisa's article Intercepting HTTP Requests I got it to work
import {TestBed, inject} from '@angular/core/testing';
import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing';
import {HTTP_INTERCEPTORS, HttpClient} from '@angular/common/http';
import {LangInterceptorService} from './lang-interceptor.service';
describe('Lang-interceptor.service', () => {
beforeEach(() => TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [{
provide: HTTP_INTERCEPTORS,
useClass: LangInterceptorService,
multi: true
}]
}));
describe('intercept HTTP requests', () => {
it('should add Accept-Language to Headers', inject([HttpClient, HttpTestingController],
(http: HttpClient, mock: HttpTestingController) => {
http.get('/api').subscribe(response => expect(response).toBeTruthy());
const request = mock.expectOne(req => (req.headers.has('Accept-Language') && req.headers.get('Accept-Language') === 'ar'));
request.flush({data: 'test'});
mock.verify();
}));
});
afterEach(inject([HttpTestingController], (mock: HttpTestingController) => {
mock.verify();
}));
});
Just make any call and mock the response with .error() method of HttpTestingController and it should work.
describe('Error interceptor', function () {
let http: HttpTestingController;
let httpClient: HttpClient;
beforeEach(() => {
const testBed = TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: MyInterceptor,
multi: true
}
],
});
http = testBed.get(HttpTestingController);
httpClient = testBed.get(HttpClient);
});
it('should catch 401', function (done) {
httpClient.get('/error').subscribe(() => {}, () => {
// Perform test
done();
});
http.expectOne('/error').error(new ErrorEvent('Unauthorized error'), {
status: 401
});
http.verify();
});
});
Interceptor testing is similar to Testing of Angular service. And TestBed is going to provide all you need to test them.
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: MyInterceptor,
multi: true
}]
});
});
describe('making http calls', () => {
it('adding header test', inject([HttpClient, YourMock], (http: HttpClient, httpMock: YourMock) => {
http.get('/data').subscribe(
response => {
expect(response).toBeTruthy();
}
);
expect(response.status).toEqual('401');
}));
});
Mocking your service will give you data which you want to duplicate during test.