介绍
AngularHttpClient
有一个测试模块,HttpClientTestingModule
可以让您对 HTTP 请求进行单元测试。
注意:由于HttpClient
仅从 Angular 4.3 开始可用,因此以下内容适用于 Angular 4.3+。如果您不熟悉 Angular 中的单元测试,请参阅此介绍。
在本文中,您将学习如何使用HttpClientTestingModule
. 这将有助于展示测试模块的功能。
先决条件
要完成本教程,您需要:
- Node.js 安装在本地,您可以按照如何安装 Node.js 和创建本地开发环境来完成。
- 对设置 Angular 项目有一定的了解。
本教程已通过 Node 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 Placeholder 通信:
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
文件:
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
:
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
,这使得模拟请求变得容易:
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
实用程序将所需的服务注入到我们的测试中。
有了这个,我们可以添加我们的测试逻辑:
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
是 typeResponse
,我们断言响应事件的主体等于我们的模拟用户。 - 然后,我们使用
HttpTestingController
(在测试中作为 注入httpMock
)来断言对服务的url
属性发出了一个请求。如果不需要请求,expectNone
也可以使用该方法。 - 我们现在可以对模拟请求进行任意数量的断言。这里我们断言请求没有被取消并且响应类型是
json
。此外,我们可以断言请求的方法 (GET
,POST
, …) - 接下来我们调用
flush
模拟请求并传入我们的模拟用户。该flush
方法使用传递给它的数据完成请求。 - 最后,我们
verify
在我们的HttpTestingController
实例上调用该方法以确保没有未完成的请求要发出。
出于本教程的目的,您可以注释掉app.component.spec.ts
.
通过运行以下命令查看测试结果:
- ng test
在浏览器中打开测试结果:
Output1 spec, 0 failures, randomized with seed 26321
DataService
should get users
它将显示成功的测试消息。
结论
在本文中,您学习了如何使用HttpClientTestingModule
.
如果您想了解有关 Angular 的更多信息,请查看我们的 Angular 主题页面以获取练习和编程项目。