Week 10 · Day 04 — 服務測試:HTTP(HttpClientTestingModule)

學習目標

  • HttpClientTestingModule 模擬 HTTP
  • HttpTestingController 驗證請求
  • req.flush() 回傳假資料

重點

為什麼要模擬 HTTP - 測試時不真正打到後端 - 可驗證「發出的請求正確」與「回傳資料能處理」

測試 UserService

import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';

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();   // 確認沒有未處理的請求
  });

  it('should get users', () => {
    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);                     // 回傳假資料
  });
});

關鍵點 - HttpClientTestingModule 取代真實 HttpClient - httpMock.expectOne(url):確認發出了符合的請求 - req.flush(data):模擬後端回應資料 - httpMock.verify():測試後確認請求都有處理

實作

  1. UserService.getUsers() 寫 HTTP 測試
  2. 驗證請求網址與方法
  3. req.flush() 回傳假資料並斷言結果

作業

  • import HttpClientTestingModule
  • HttpTestingController.expectOne 驗證請求
  • req.flush() 回傳資料並測試邏輯