Setting Up HTTP Testing
HttpTestingController replaces the real backend so tests never hit the network.
Enabling HTTP Testing
import { TestBed } from '@angular/core/testing';
import { provideHttpClient } from '@angular/common/http';
import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing';
import { UserService } from './user.service';
describe('UserService', () => {
let service: UserService;
let httpMock: HttpTestingController;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
provideHttpClient(),
provideHttpClientTesting(),
UserService,
],
});
service = TestBed.inject(UserService);
httpMock = TestBed.inject(HttpTestingController);
});
afterEach(() => {
httpMock.verify(); // Assert no outstanding requests
});
});
Asserting a GET Request
it('should fetch users', () => {
const mockUsers: User[] = [
{ id: 1, name: 'Alice', email: 'alice@example.com' },
{ id: 2, name: 'Bob', email: 'bob@example.com' },
];
service.getUsers().subscribe(users => {
expect(users).toEqual(mockUsers);
});
const req = httpMock.expectOne('/api/users');
expect(req.request.method).toBe('GET');
req.flush(mockUsers);
});
HttpTestingController Methods
| Method | Purpose |
|---|---|
expectOne(url) |
Assert exactly one request to URL |
expectNone(url) |
Assert no requests to URL |
match(url) |
Find all matching requests |
verify() |
Assert no outstanding requests |
flush — Simulate Success
const req = httpMock.expectOne('/api/users');
req.flush(mockUsers); // Emit response and complete
error — Simulate Failure
const req = httpMock.expectOne('/api/users');
req.error(new ErrorEvent('Network error'), { status: 500, statusText: 'Server Error' });
Advanced HTTP Testing
HttpTestingController supports testing headers, query params, and request bodies.
Asserting Request Details
it('should send auth header', () => {
service.getUsers().subscribe();
const req = httpMock.expectOne('/api/users');
expect(req.request.headers.get('Authorization')).toBe('Bearer token123');
expect(req.request.method).toBe('GET');
req.flush([]);
});
Asserting POST Body
it('should create a user', () => {
const newUser = { name: 'Alice', email: 'alice@example.com' };
service.createUser(newUser).subscribe();
const req = httpMock.expectOne('/api/users');
expect(req.request.method).toBe('POST');
expect(req.request.body).toEqual(newUser);
req.flush({ id: 1, ...newUser });
});
Testing Query Parameters
it('should send query params', () => {
service.searchUsers('alice', 1).subscribe();
const req = httpMock.expectOne(
req => req.url === '/api/users/search' &&
req.params.get('q') === 'alice' &&
req.params.get('page') === '1'
);
req.flush([]);
});
Testing Error Handling
it('should handle 404 error', () => {
service.getUser(999).subscribe({
error: err => {
expect(err.message).toContain('not found');
},
});
const req = httpMock.expectOne('/api/users/999');
req.flush('Not found', { status: 404, statusText: 'Not Found' });
});
Quiz
1. What does HttpTestingController do?
2. What does expectOne(url) do?
3. How do you simulate a server error in tests?
Flashcards
Question
What does HttpTestingController do?
Click to reveal answer
Answer
Replaces the real backend. Tests assert requests and simulate responses without network calls.
Question
What does expectOne(url) do?
Click to reveal answer
Answer
Asserts exactly one request was made to the URL. Returns TestRequest for assertions.
Question
How do you simulate errors?
Click to reveal answer
Answer
req.error(new ErrorEvent('...'), { status: 500 }) — simulates server failure.
Revision Notes
Key Takeaways
- 1. provideHttpClientTesting replaces the real backend
- 2. expectOne asserts exactly one request to a URL
- 3. flush simulates success, error simulates failure
- 4. verify() ensures no outstanding requests
Interview Tips
- • Explain how HttpTestingController works
- • Be ready to describe request assertion patterns
- • Mention testing error handling with req.error()
Cheat Sheet
HTTP Testing Cheat Sheet
Setup:
TestBed.configureTestingModule({
providers: [provideHttpClient(), provideHttpClientTesting()]
});
Assert request:
const req = httpMock.expectOne('/api/users');
expect(req.request.method).toBe('GET');
req.flush(mockData);
Simulate error:
req.error(new ErrorEvent('Network error'), { status: 500 });
Verify no outstanding:
httpMock.verify(); // in afterEach