0
0
Angularframework~5 mins

Testing HTTP calls with HttpTestingController in Angular

Choose your learning style9 modes available
Introduction

We use HttpTestingController to check if our Angular app makes the right HTTP requests without actually calling a server.

You want to test if your service sends the correct GET or POST request.
You want to simulate server responses to see how your app reacts.
You want to make sure no unexpected HTTP calls happen during a test.
Syntax
Angular
import { HttpTestingController, HttpClientTestingModule } from '@angular/common/http/testing';

beforeEach(() => {
  TestBed.configureTestingModule({
    imports: [HttpClientTestingModule],
    providers: [YourService]
  });

  httpTestingController = TestBed.inject(HttpTestingController);
  service = TestBed.inject(YourService);
});

// In your test
const req = httpTestingController.expectOne('url');
expect(req.request.method).toBe('GET');
req.flush(mockData);

httpTestingController.verify();

Always import HttpClientTestingModule to use HttpTestingController.

Call httpTestingController.verify() to check no unexpected requests remain.

Examples
This checks a GET request to 'api/data' and sends back mock data.
Angular
const req = httpTestingController.expectOne('api/data');
expect(req.request.method).toBe('GET');
req.flush({id: 1, name: 'Test'});
This checks a POST request to 'api/save' and returns a success response.
Angular
const req = httpTestingController.expectOne('api/save');
expect(req.request.method).toBe('POST');
req.flush({success: true});
Sample Program

This test checks that DataService.getData() sends a GET request to 'api/data' and receives the expected mock data.

Angular
import { TestBed } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';

@Injectable()
class DataService {
  constructor(private http: HttpClient) {}

  getData() {
    return this.http.get<{id: number; name: string}>('api/data');
  }
}

describe('DataService with HttpTestingController', () => {
  let service: DataService;
  let httpTestingController: HttpTestingController;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule],
      providers: [DataService]
    });

    service = TestBed.inject(DataService);
    httpTestingController = TestBed.inject(HttpTestingController);
  });

  it('should fetch data with GET request', (done) => {
    const mockResponse = {id: 1, name: 'Test Item'};

    service.getData().subscribe(data => {
      expect(data).toEqual(mockResponse);
      done();
    });

    const req = httpTestingController.expectOne('api/data');
    expect(req.request.method).toBe('GET');
    req.flush(mockResponse);

    httpTestingController.verify();
  });
});
OutputSuccess
Important Notes

Use expectOne() to find a single HTTP request by URL.

Use flush() to simulate the server sending back data.

Always call verify() to ensure no unexpected HTTP calls remain after the test.

Summary

HttpTestingController helps test HTTP calls without real servers.

Use expectOne() to check requests and flush() to send mock responses.

Always verify no extra requests remain with verify().