How to mock HttpClient in Angular tests

Testing components and services that make HTTP requests requires mocking to avoid actual API calls and ensure tests run fast and reliably. With over 12 years of Angular development experience since 2014 and as the creator of CoreUI, I’ve written extensive test suites for HTTP-based services. Angular provides HttpClientTestingModule and HttpTestingController specifically for mocking HTTP requests in tests. This approach allows you to verify requests are made correctly and control response data for different test scenarios.

Use HttpClientTestingModule and HttpTestingController to mock HTTP requests and verify API calls.

import { TestBed } from '@angular/core/testing'
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'
import { UserService } from './user.service'

describe('UserService', () => {
  let service: UserService
  let httpMock: HttpTestingController

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule],
      providers: [UserService]
    })
    service = TestBed.inject(UserService)
    httpMock = TestBed.inject(HttpTestingController)
  })

  afterEach(() => {
    httpMock.verify() // Ensure no outstanding requests
  })

  it('should fetch users from API', () => {
    const mockUsers = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Jane' }
    ]

    service.getUsers().subscribe(users => {
      expect(users.length).toBe(2)
      expect(users).toEqual(mockUsers)
    })

    const req = httpMock.expectOne('https://api.example.com/users')
    expect(req.request.method).toBe('GET')
    req.flush(mockUsers)
  })

  it('should send POST request with data', () => {
    const newUser = { name: 'Bob', email: '[email protected]' }

    service.createUser(newUser).subscribe(user => {
      expect(user.id).toBe(3)
    })

    const req = httpMock.expectOne('https://api.example.com/users')
    expect(req.request.method).toBe('POST')
    expect(req.request.body).toEqual(newUser)
    req.flush({ id: 3, ...newUser })
  })

  it('should handle HTTP errors', () => {
    service.getUsers().subscribe(
      () => fail('should have failed'),
      (error) => {
        expect(error.status).toBe(404)
        expect(error.error).toBe('Not found')
      }
    )

    const req = httpMock.expectOne('https://api.example.com/users')
    req.flush('Not found', { status: 404, statusText: 'Not Found' })
  })

  it('should include authorization header', () => {
    service.getUserById(1).subscribe()

    const req = httpMock.expectOne('https://api.example.com/users/1')
    expect(req.request.headers.get('Authorization')).toBe('Bearer token123')
    req.flush({ id: 1, name: 'John' })
  })

  it('should handle multiple requests', () => {
    service.getUsers().subscribe()
    service.getUserById(1).subscribe()

    const requests = httpMock.match(req => req.url.includes('users'))
    expect(requests.length).toBe(2)
    requests.forEach(req => req.flush([]))
  })
})

Best Practice Note

Always call httpMock.verify() in afterEach to ensure no unexpected HTTP requests were made. Use expectOne() for single requests and match() for multiple requests. The flush() method simulates the server response with mock data. Test both success and error scenarios including different HTTP status codes. For services with interceptors, the interceptors will run in tests unless you explicitly skip them. This is the testing strategy we use in CoreUI for Angular—comprehensive HTTP mocking to ensure services handle all API scenarios correctly without making actual network calls.


Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


About the Author

Subscribe to our newsletter
Get early information about new products, product updates and blog posts.
How to force a React component to re-render
How to force a React component to re-render

How to check if an element is visible in JavaScript
How to check if an element is visible in JavaScript

How to loop through a 2D array in JavaScript
How to loop through a 2D array in JavaScript

Passing props to child components in React function components
Passing props to child components in React function components

Answers by CoreUI Core Team