Testing Angular HTTP Services using Jest

The tests check if the HTTP service works correctly by: Making fake API calls (GET/POST) Returning test data Handling errors properly All without using real internet connections This ensures the service works as expected before using it in real apps. data-http-service.ts import { Injectable, inject } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; const API_URL = 'https://api.example.com/data'; @Injectable({ providedIn: 'root' }) export class DataHttpService { http = inject(HttpClient); getData(): Observable { return this.http.get(API_URL); } postData(payload: unknown): Observable { return this.http.post(API_URL, payload); } } data-http-service.spec.ts import { TestBed } from '@angular/core/testing'; import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; import { DataHttpService } from './data-http.service'; describe('DataHttpService', () => { let service: DataHttpService; let httpMock: HttpTestingController; const API_URL = 'https://api.example.com/data'; const mockData = { id: 1, name: 'Test Data' }; beforeEach(() => { TestBed.configureTestingModule({ imports: [HttpClientTestingModule], providers: [DataHttpService] }); service = TestBed.inject(DataHttpService); httpMock = TestBed.inject(HttpTestingController); }); afterEach(() => { httpMock.verify(); // Verify no outstanding requests }); it('should be created', () => { expect(service).toBeTruthy(); }); describe('.getData', () => { it('should make GET request and return data', () => { service.getData().subscribe(data => { expect(data).toEqual(mockData); }); const req = httpMock.expectOne(API_URL); expect(req.request.method).toEqual('GET'); req.flush(mockData); }); it('should handle GET errors', () => { const mockError = { status: 404, statusText: 'Not Found' }; service.getData().subscribe({ next: () => fail('Should have failed'), error: (error) => { expect(error.status).toEqual(mockError.status); } }); const req = httpMock.expectOne(API_URL); req.flush(null, mockError); }); }); describe('.postData', () => { it('should make POST request with payload', () => { const testPayload = { data: 'test' }; service.postData(testPayload).subscribe(data => { expect(data).toEqual(mockData); }); const req = httpMock.expectOne(API_URL); expect(req.request.method).toEqual('POST'); expect(req.request.body).toEqual(testPayload); req.flush(mockData); }); it('should handle POST errors', () => { const testPayload = { data: 'test' }; const mockError = { status: 500, statusText: 'Server Error' }; service.postData(testPayload).subscribe({ next: () => fail('Should have failed'), error: (error) => { expect(error.status).toEqual(mockError.status); } }); const req = httpMock.expectOne(API_URL); req.flush(null, mockError); }); }); });

Apr 18, 2025 - 13:20
 0
Testing Angular HTTP Services using Jest

The tests check if the HTTP service works correctly by:

  1. Making fake API calls (GET/POST)
  2. Returning test data
  3. Handling errors properly
  4. All without using real internet connections

This ensures the service works as expected before using it in real apps.

data-http-service.ts

import { Injectable, inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

const API_URL = 'https://api.example.com/data';

@Injectable({
  providedIn: 'root'
})
export class DataHttpService {
  http = inject(HttpClient);

  getData(): Observable<unknown> {
    return this.http.get<unknown>(API_URL);
  }

  postData(payload: unknown): Observable<unknown> {
    return this.http.post<unknown>(API_URL, payload);
  }

}

data-http-service.spec.ts

import { TestBed } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { DataHttpService } from './data-http.service';

describe('DataHttpService', () => {
  let service: DataHttpService;
  let httpMock: HttpTestingController;
  const API_URL = 'https://api.example.com/data';
  const mockData = { id: 1, name: 'Test Data' };

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

    service = TestBed.inject(DataHttpService);
    httpMock = TestBed.inject(HttpTestingController);
  });

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


  it('should be created', () => {
    expect(service).toBeTruthy();
  });

  describe('.getData', () => {
    it('should make GET request and return data', () => {
      service.getData().subscribe(data => {
        expect(data).toEqual(mockData);
      });

      const req = httpMock.expectOne(API_URL);
      expect(req.request.method).toEqual('GET');
      req.flush(mockData);
    });

    it('should handle GET errors', () => {
      const mockError = { status: 404, statusText: 'Not Found' };

      service.getData().subscribe({
        next: () => fail('Should have failed'),
        error: (error) => {
          expect(error.status).toEqual(mockError.status);
        }
      });

      const req = httpMock.expectOne(API_URL);
      req.flush(null, mockError);
    });
  });

  describe('.postData', () => {
    it('should make POST request with payload', () => {
      const testPayload = { data: 'test' };

      service.postData(testPayload).subscribe(data => {
        expect(data).toEqual(mockData);
      });

      const req = httpMock.expectOne(API_URL);
      expect(req.request.method).toEqual('POST');
      expect(req.request.body).toEqual(testPayload);
      req.flush(mockData);
    });

    it('should handle POST errors', () => {
      const testPayload = { data: 'test' };
      const mockError = { status: 500, statusText: 'Server Error' };

      service.postData(testPayload).subscribe({
        next: () => fail('Should have failed'),
        error: (error) => {
          expect(error.status).toEqual(mockError.status);
        }
      });

      const req = httpMock.expectOne(API_URL);
      req.flush(null, mockError);
    });
  });

});