スポンサーリンク

Angular × VitestでHttpClientをモックする方法

この記事は「Angular × Vite ユニットテスト入門|Vitestで始めるテスト完全ガイド」シリーズの一部です。

Angular × VitestでHttpClientのモックについて

AngularでHTTP通信を行うサービスやコンポーネントをテストする際、実際のAPIを叩いてしまうとテストが不安定になります。
そのため、HttpClientは必ずモック化してテストする必要があります。

なぜHttpClientのモックが必要なのか

HTTP通信は外部依存であり、そのままテストすると以下の問題が発生します。

  • APIの状態に依存してテストが壊れる
  • テストが遅くなる
  • オフラインで実行できない

Angular公式でも、HTTPは必ずモックしてテストすることが推奨されています。
HTTPテストでは、リクエストを検証し、レスポンスを任意に制御できる仕組みが提供されています。

Angularの最新HttpClientモック方法(重要)

従来は HttpClientTestingModule を使っていましたが、現在は非推奨(deprecated)です。

代わりに以下を使用します。

  • provideHttpClient()
  • provideHttpClientTesting()

これはAngular公式ドキュメントでも明確に示されています。

基本構成(Vitest対応)

テストのセットアップ

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

  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [
        UserService,
        provideHttpClient(),
        provideHttpClientTesting(),
      ],
    });

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

  afterEach(() => {
    httpMock.verify(); // 未処理のリクエストがないことを確認
  });

  it('GETリクエストが正しく呼ばれる', async () => {
    const mockResponse = [{ id: 1, name: 'test' }];

    const promise = firstValueFrom(service.getUsers());

    const req = httpMock.expectOne('/api/users');
    expect(req.request.method).toBe('GET');

    req.flush(mockResponse);

    const result = await promise;
    expect(result).toEqual(mockResponse);
  });
});

HttpTestingControllerの役割

HttpTestingControllerは、HTTPモックの中核です。

できること:

  • リクエストの検証(URL・methodなど)
  • レスポンスの強制返却(flush)
  • 不要なリクエスト検出

Angular公式でも、以下の流れが推奨されています。

  1. サービスを実行
  2. リクエストを捕捉
  3. 検証
  4. モックレスポンスを返却

サービス側の例

@Injectable({ providedIn: 'root' })
export class UserService {
constructor(private http: HttpClient) {}

getUsers() {
return this.http.get<any[]>('/api/users');
}
}

エラーケースのテスト

  it('エラー時の処理', async () => {
      const promise = firstValueFrom(service.getUsers()).catch(e => e);

      const req = httpMock.expectOne('/api/users');

      req.flush('error', {
        status: 500,
        statusText: 'Server Error',
      });

      const error = await promise;
      expect(error.status).toBe(500);
  });

まとめ

Angular × VitestでHttpClientをモックする場合は、以下がベストプラクティスです。

  • provideHttpClient() を使う
  • provideHttpClientTesting() を使う
  • HttpTestingControllerで検証・レスポンス制御
  • HttpClientの手動モックは避ける

特に重要なのは、HttpClientTestingModuleは非推奨になっている点です。
今後は必ず新しいAPIを使いましょう。