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/core
v12.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トピックページで演習とプログラミングプロジェクトを確認してください。