AngularでHttpClientリクエストをテストする方法
序章
AngularのHttpClientには、HTTPリクエストの単体テストを可能にするテストモジュールHttpClientTestingModuleがあります。
注: HttpClientはAngular4.3以降でのみ使用可能であるため、Angular4.3以降には以下が適用されます。 Angularでの単体テストを初めて使用する場合は、この紹介を参照してください。
この記事では、HttpClientTestingModuleを使用してHTTPGETリクエストの単体テストを設定する方法を学習します。 これは、テストモジュールの機能を示すのに役立ちます。
前提条件
このチュートリアルを完了するには、次のものが必要です。
- Node.jsはローカルにインストールされます。これは、Node.jsのインストール方法とローカル開発環境の作成に従って実行できます。
- Angularプロジェクトのセットアップにある程度精通している。
このチュートリアルは、ノードv16.2.0、npm v7.15.1、および@angular/corev12.0.4で検証されました。
ステップ1—プロジェクトの設定
この投稿では、エンドポイントからデータを取得するサービスと、そのサービスを呼び出してコンポーネントのOnInitフックにユーザーのリストを入力するコンポーネントを使用します。
@angular/cliを使用して、新しいプロジェクトを作成できます。
ng new angular-httpclienttest-example
次に、新しく作成されたプロジェクトディレクトリに移動します。
cd angular-httpclienttest-example
data.service.tsを作成します:
ng generate service data
そして、JSONプレースホルダーと通信します。
src / app / data.service.ts
import { Injectable } from '@angular/core';
import { HttpClient, HttpRequest } from '@angular/common/http';
@Injectable({ ... })
export class DataService {
url = 'https://jsonplaceholder.typicode.com/users';
constructor(private http: HttpClient) { }
getData() {
const req = new HttpRequest('GET', this.url, {
reportProgress: true
});
return this.http.request(req);
}
}
次に、app.component.tsファイルを変更します。
src / app.component.ts
import { Component, OnInit } from '@angular/core';
import { HttpEvent, HttpEventType } from '@angular/common/http';
import { DataService } from './data.service';
@Component({ ... })
export class AppComponent implements OnInit {
users: any;
constructor(private dataService: DataService) {}
ngOnInit() {
this.populateUsers();
}
private populateUsers() {
this.dataService.getData().subscribe((event: HttpEvent<any>) => {
switch (event.type) {
case HttpEventType.Sent:
console.log('Request sent!');
break;
case HttpEventType.ResponseHeader:
console.log('Response header received!');
break;
case HttpEventType.DownloadProgress:
const kbLoaded = Math.round(event.loaded / 1024);
console.log(`Download in progress! ${kbLoaded}Kb loaded`);
break;
case HttpEventType.Response:
console.log('Done!', event.body);
this.users = event.body;
}
});
}
}
そして、HttpClientmoduleをapp.module.tsに追加します。
src / app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
この時点で、サービスとクライアントを備えたAngularプロジェクトが作成されます。
ステップ2—テストを追加する
次に、データサービスのスペックファイルを設定し、HttpClientリクエストをテストするために必要なユーティリティを含めます。 HttpClientTestingModuleに加えて、HttpTestingControllerも必要です。これにより、リクエストを簡単にモックできます。
data.service.spec.ts
import { TestBed, inject } from '@angular/core/testing';
import { HttpEvent, HttpEventType } from '@angular/common/http';
import {
HttpClientTestingModule,
HttpTestingController
} from '@angular/common/http/testing';
import { DataService } from './data.service';
describe('DataService', () => {
let service: DataService;
beforeEach(() => {
TestBed.configureTestingModule({}
imports: [HttpclientTestingModule],
providers: [DataService]
);
service = TestBed.inject(DataService);
});
});
injectユーティリティを使用して、必要なサービスをテストに注入します。
これが整ったら、テストロジックを追加できます。
data.service.spec.ts
import { TestBed, inject } from '@angular/core/testing';
import { HttpEvent, HttpEventType } from '@angular/common/http';
import {
HttpClientTestingModule,
HttpTestingController
} from '@angular/common/http/testing';
import { DataService } from './data.service';
describe('DataService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [DataService]
});
});
it(
'should get users',
inject(
[HttpTestingController, DataService],
(httpMock: HttpTestingController, dataService: DataService) => {
const mockUsers = [
{ name: 'Alice', website: 'example.com' },
{ name: 'Bob', website: 'example.org' }
];
dataService.getData().subscribe((event: HttpEvent<any>) => {
switch (event.type) {
case HttpEventType.Response:
expect(event.body).toEqual(mockUsers);
}
});
const mockReq = httpMock.expectOne(dataService.url);
expect(mockReq.cancelled).toBeFalsy();
expect(mockReq.request.responseType).toEqual('json');
mockReq.flush(mockUsers);
httpMock.verify();
}
)
);
});
かなりのことが起こっているので、それを分解しましょう:
- まず、テストする模擬ユーザーをいくつか定義します。
- 次に、テストしているサービスで
getDataメソッドを呼び出し、返されたobservableをサブスクライブします。 HttpEventTypeのタイプがResponseの場合、応答イベントの本文がモックユーザーと等しいことを表明します。- 次に、
HttpTestingController(テストではhttpMockとして挿入)を使用して、サービスのurlプロパティに対して1つの要求が行われたことを表明します。 リクエストが予想されない場合は、expectNoneメソッドを使用することもできます。 - これで、モックリクエストに対して任意の数のアサーションを作成できます。 ここでは、要求がキャンセルされておらず、応答のタイプが
jsonであると断言します。 さらに、リクエストのメソッドをアサートすることもできます(GET、POST、…) - 次に、モックリクエストで
flushを呼び出し、モックユーザーを渡します。flushメソッドは、渡されたデータを使用してリクエストを完了します。 - 最後に、
HttpTestingControllerインスタンスでverifyメソッドを呼び出して、未処理のリクエストがないことを確認します。
このチュートリアルでは、app.component.spec.tsをコメントアウトできます。
次のコマンドを実行して、テストの結果を確認します。
ng test
ブラウザでテスト結果を開きます。
Output1 spec, 0 failures, randomized with seed 26321 DataService should get users
成功したテストメッセージが表示されます。
結論
この記事では、HttpClientTestingModuleを使用してHTTPGETリクエストの単体テストを設定する方法を学習しました。
Angularについて詳しく知りたい場合は、Angularトピックページで演習とプログラミングプロジェクトを確認してください。