はじめに
WebAPI通信部分のテストをするときに必ずかいているテストコードが2つあるので忘れないようにメモ。
環境
- Angular v16
- Karma+Jasmine
期待通りのHTTPリクエストが行われているか
it('GETリクエストが行われている', () => {
service.fetchHogeList$().subscribe();
const req = httpTestingController.expectOne('https://hoge/test');
expect('GET').toEqual(req.request.method);
});
expectOne
期待するURLと通信の種類(POSTとかGETとか)を使用するリクエストが
よばれたことを確認する。
期待通りのデータの取得ができているか
it('期待通りのデータが取得できている', fakeAsync(() => {
const expected: HogeListModel[] = [
{
hogeId: 'hogeId1',
hogeName: 'hogehoge',
}
];
service.fetchHogeList$().subscribe(actual => {
expect(expected).toEqual(actual);
});
const req = httpTestingController.expectOne('https://hoge/test');
req.flush(expected);
}));
fakeAsync
非同期の操作を同期の形でテストできる。
サポートする非同期操作
- Promise
- setTimeout など
このテストでは使っていないが、tick()関数を使うと、特定の時間が経過した後の状態をテストすることができる。
flush
このテストではサーバーからの応答を疑似的にすることで、データをレスポンスとして返している。
非同期のHTTPリクエストを同期的にテストすることができる。
テストコード全文
import { TestBed, fakeAsync } from '@angular/core/testing';
import { AppService, HogeListModel } from './app.service';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
describe('AppService', () => {
let service: AppService;
let httpTestingController: HttpTestingController;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
HttpClientTestingModule
]
});
service = TestBed.inject(AppService);
httpTestingController = TestBed.inject(HttpTestingController);
});
it('GETリクエストが行われている', () => {
service.fetchHogeList$().subscribe();
const req = httpTestingController.expectOne('https://hoge/test');
expect('GET').toEqual(req.request.method);
});
it('期待通りのデータが取得できている', fakeAsync(() => {
const expected: HogeListModel[] = [
{
hogeId: 'hogeId1',
hogeName: 'hogehoge',
}
];
service.fetchHogeList$().subscribe(actual => {
expect(expected).toEqual(actual);
});
const req = httpTestingController.expectOne('https://hoge/test');
req.flush(expected);
}));
});
HttpClientTestingModule
HttpClientをテストするためのモジュール。
リクエストのモック化とフラッシュが可能になる。
https://angular.jp/api/common/http/testing/HttpTestingController#httptestingcontroller
テストしていたコード
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class AppService {
constructor(
private readonly httpClient: HttpClient,
) { }
public fetchHogeList$(): Observable<HogeListModel[]> {
return this.httpClient.get<HogeListModel[]>(
'https://hoge/test'
);
}
}
export interface HogeListModel {
hogeId: string;
hogeName: string;
}