All topics
Testingintermediate

Testing HTTP with HttpClientTestingModule

Explain how HttpClientTestingModule and HttpTestingController let you assert on and mock outgoing HTTP requests.

Testing code that calls HttpClient shouldn't make real network requests — that would make tests slow, flaky (dependent on network conditions and a real backend being available), and hard to control for specific edge cases like error responses. HttpClientTestingModule (or, in newer standalone-based setups, provideHttpClientTesting()) replaces HttpClient's real backend with a controllable mock, and HttpTestingController is the test utility for asserting on and responding to the requests that were actually made.

It's like testing a mail-order process using a fake postal counter that lets you specify exactly what response letter comes back for any given outgoing request, and then checking the counter's logbook at the end to make sure no unexpected letters were mailed that you didn't account for.

Key Concepts

1
The typical pattern: call the service method under test (which internally triggers an HTTP call), then use httpMock.expectOne(url) to assert that exactly one request matching the given URL (or a predicate function) was made, and then call .flush(mockResponseData) on the returned TestRequest object to simulate the server responding with specific mock data — synchronously completing the Observable the service code is waiting on, entirely without any real network activity.
httpMock.expectOne(url).flush(mockResponseData)TestRequest
2
This pattern is equally suited to testing error handling: instead of .flush(data), calling .flush(errorBody, { status: 500, statusText: 'Server Error' }) (or .error(new ProgressEvent('error')) for network-level failures) simulates a failed HTTP response, letting you verify the service or component correctly handles that failure case, which is difficult to reliably reproduce against a real backend on demand.
.flush(data).flush(errorBody, { status: 500, statusText: 'Server Error' }).error(new ProgressEvent('error'))
3
A critical, easy-to-forget step interviewers like to test knowledge of: calling httpMock.verify() (typically in an afterEach) to assert that no unexpected/unmatched HTTP requests were made during the test — this catches a whole category of bugs where code fires an HTTP request the test didn't anticipate or account for, which would otherwise silently pass unnoticed.
httpMock.verify()afterEach