Using HttpTestingModule
For versions of Angular 5 and above.
Using the HttpClientTestingModule and HttpTestingController provided by Angular makes mocking out results and testing http requests simple by providing many useful methods for checking http requests and providing mock responses for each request.

Breakdown of the Testing Strategy

For each test, we make a call to the service we would like to test. In the subscribe block we create an assertion using expect that will run when we receive a result.
1
searchWikiService.search('Angular').subscribe(
2
res => expect(res).toEqual(mockResponse, 'should return expected results'),
3
fail
4
);
Copied!
In this case, we expect the response from the search method to be the mockResponse we will provide in the next steps.

Check Http Requests

Next, we can check the details of the http request. In this case we can check that a 'POST'request to the url we expect was made, like so:
1
const req = httpTestingController.expectOne(searchWikiService.searchUrl);
2
expect(req.request.method).toEqual('POST');
Copied!
In this case, the expectOnemethod of httpTestingController also checks that only one request that uses POST and the url we expect was made when we call the search . There are other methods that httpTestingController provides such as match (checks for any matching requests) and expectNone(checks that no matching requests are found).

Using .flush()

The request captured by the httpTestingController, req, has a flush method on it which takes in whatever response you would like to provide for that request as an argument.
1
req.flush(mockResponse);
Copied!

Verify All Requests are Complete

Once all req have been provided a response using flush, we can verify that there are no more pending requests after the test.
1
httpTestingController.verify();
Copied!

Complete Spec Example:

Below is a complete example showing a few different test cases for our search service that checks a few different mock responses we might expect to get: multiple results, no results and an error.
1
// Http testing module and mocking controller
2
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
3
4
// Other imports
5
import { TestBed } from '@angular/core/testing';
6
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
7
8
import {SearchWikiService} from './wikisearch.service';
9
10
const mockResponse = {
11
"batchcomplete": "",
12
"continue": {
13
"sroffset": 10,
14
"continue": "-||"
15
},
16
"query": {
17
"searchinfo": {
18
"totalhits": 36853
19
},
20
"search": [{
21
"ns": 0,
22
"title": "Stuff",
23
"snippet": "<span></span>",
24
"size": 1906,
25
"wordcount": 204,
26
"timestamp": "2016-06-10T17:25:36Z"
27
}]
28
}
29
};
30
31
describe('Wikipedia search service', () => {
32
33
beforeEach(() => {
34
TestBed.configureTestingModule({
35
// Import the HttpClient mocking services
36
imports: [ HttpClientTestingModule ],
37
// Provide the service-under-test and its dependencies
38
providers: [
39
SearchWikiService
40
]
41
});
42
43
// Inject the http, test controller, and service-under-test
44
// as they will be referenced by each test.
45
httpClient = TestBed.get(HttpClient);
46
httpTestingController = TestBed.get(HttpTestingController);
47
searchWikiService = TestBed.get(SearchWikiService);
48
});
49
50
afterEach(() => {
51
// After every test, assert that there are no more pending requests.
52
httpTestingController.verify();
53
});
54
55
it('should get search results', () => {
56
57
searchWikiService.search('Angular').subscribe(
58
res => expect(res).toEqual(mockResponse, 'should return expected results'),
59
fail
60
);
61
62
// Check for correct requests: should have made one request to POST search from expected URL
63
const req = httpTestingController.expectOne(searchWikiService.searchUrl);
64
expect(req.request.method).toEqual('POST');
65
66
// Provide each request with a mock response
67
req.flush(mockResponse);
68
));
69
70
it('should be OK returning no matching search results', () => {
71
72
searchWikiService.search('Angular').subscribe(
73
res => expect(res.length).toEqual(0, 'should have empty search array'),
74
fail
75
);
76
77
const req = httpTestingController.expectOne(searchWikiService.searchUrl);
78
req.flush([]); // Respond with empty search results
79
});
80
81
// TEST ERROR CASES BY MOCKING ERROR RESPONSE
82
it('should turn 404 into an empty result', () => {
83
84
searchWikiService.search('Angular').subscribe(
85
res => expect(res.length).toEqual(0, 'should return empty results array'),
86
fail
87
);
88
89
const req = httpTestingController.expectOne(searchWikiService.searchUrl);
90
91
// respond with an error to test how its handled, in this case a 404
92
const msg = 'nothing found';
93
req.flush(msg, {status: 404, statusText: 'Not Found'});
94
});
95
96
});
Copied!
Last modified 2yr ago