简介
Angel的HttpClient
有一个测试模块HttpClientTestingModule
,,它使您能够对HTTPS请求进行单元测试。
<$>[注]
注意: 由于HttpClient
仅从Angular 4.3开始可用,因此以下内容适用于Angular 4.3+。如果你是Angular单元测试的新手,请参考这篇介绍。
<$>
在本文中,您将了解如何使用HttpClientTestingModule
为HTTP GET请求设置单元测试。这将有助于演示测试模块的功能。
预约
要完成本教程,您需要:
- 本地安装node.js,可按照如何安装node.js并创建本地开发Environment.
- 对设置角度project.》有所了解
本教程已经在Node v16.2.0、npm
v7.15.1和@angular/core
v12.0.4上进行了验证。
第一步-设置项目
在本文中,我们将使用一个从端点获取数据的服务,以及一个调用该服务以填充组件的OnInit
钩子中的用户列表的组件。
您可以使用@angular/cli
创建一个新项目:
1ng new angular-httpclienttest-example
然后,导航到新创建的项目目录:
1cd angular-httpclienttest-example
在data.service.ts
创建:
1ng generate service data
让它与JSON Placeholder通信:
1[label src/app/data.service.ts]
2import { Injectable } from '@angular/core';
3import { HttpClient, HttpRequest } from '@angular/common/http';
4
5@Injectable({ ... })
6export class DataService {
7 url = 'https://jsonplaceholder.typicode.com/users';
8
9 constructor(private http: HttpClient) { }
10
11 getData() {
12 const req = new HttpRequest('GET', this.url, {
13 reportProgress: true
14 });
15
16 return this.http.request(req);
17 }
18}
然后修改app.component.ts
文件:
1[label src/app.component.ts]
2import { Component, OnInit } from '@angular/core';
3import { HttpEvent, HttpEventType } from '@angular/common/http';
4
5import { DataService } from './data.service';
6
7@Component({ ... })
8export class AppComponent implements OnInit {
9 users: any;
10
11 constructor(private dataService: DataService) {}
12
13 ngOnInit() {
14 this.populateUsers();
15 }
16
17 private populateUsers() {
18 this.dataService.getData().subscribe((event: HttpEvent<any>) => {
19 switch (event.type) {
20 case HttpEventType.Sent:
21 console.log('Request sent!');
22 break;
23 case HttpEventType.ResponseHeader:
24 console.log('Response header received!');
25 break;
26 case HttpEventType.DownloadProgress:
27 const kbLoaded = Math.round(event.loaded / 1024);
28 console.log(`Download in progress! ${kbLoaded}Kb loaded`);
29 break;
30 case HttpEventType.Response:
31 console.log('Done!', event.body);
32 this.users = event.body;
33 }
34 });
35 }
36}
并将HttpClientmode
添加到app.mode.ts
:
1[label src/app.module.ts]
2import { NgModule } from '@angular/core';
3import { BrowserModule } from '@angular/platform-browser';
4import { HttpClientModule } from '@angular/common/http';
5
6import { AppComponent } from './app.component';
7
8@NgModule({
9 declarations: [
10 AppComponent
11 ],
12 imports: [
13 BrowserModule,
14 HttpClientModule
15 ],
16 providers: [],
17 bootstrap: [AppComponent]
18})
19export class AppModule { }
在这一点上,您将拥有一个带有服务和客户端的角度项目。
Step 2 -添加测试
现在,我们将为数据服务设置一个spec文件,并包含必要的实用程序来测试HttpClient
请求。在HttpClientTestingModule
之上,我们还需要HttpTestingController
,它可以很容易地模拟请求:
1[label data.service.spec.ts]
2import { TestBed, inject } from '@angular/core/testing';
3import { HttpEvent, HttpEventType } from '@angular/common/http';
4import {
5 HttpClientTestingModule,
6 HttpTestingController
7} from '@angular/common/http/testing';
8
9import { DataService } from './data.service';
10
11describe('DataService', () => {
12 let service: DataService;
13
14 beforeEach(() => {
15 TestBed.configureTestingModule({}
16 imports: [HttpclientTestingModule],
17 providers: [DataService]
18 );
19 service = TestBed.inject(DataService);
20 });
21});
我们使用`ins‘实用程序将所需的服务注入到我们的测试中。
有了这些,我们就可以添加我们的测试逻辑:
1[label data.service.spec.ts]
2import { TestBed, inject } from '@angular/core/testing';
3import { HttpEvent, HttpEventType } from '@angular/common/http';
4import {
5 HttpClientTestingModule,
6 HttpTestingController
7} from '@angular/common/http/testing';
8
9import { DataService } from './data.service';
10
11describe('DataService', () => {
12 beforeEach(() => {
13 TestBed.configureTestingModule({
14 imports: [HttpClientTestingModule],
15 providers: [DataService]
16 });
17 });
18 it(
19 'should get users',
20 inject(
21 [HttpTestingController, DataService],
22 (httpMock: HttpTestingController, dataService: DataService) => {
23 const mockUsers = [
24 { name: 'Alice', website: 'example.com' },
25 { name: 'Bob', website: 'example.org' }
26 ];
27
28 dataService.getData().subscribe((event: HttpEvent<any>) => {
29 switch (event.type) {
30 case HttpEventType.Response:
31 expect(event.body).toEqual(mockUsers);
32 }
33 });
34
35 const mockReq = httpMock.expectOne(dataService.url);
36
37 expect(mockReq.cancelled).toBeFalsy();
38 expect(mockReq.request.responseType).toEqual('json');
39 mockReq.flush(mockUsers);
40
41 httpMock.verify();
42 }
43 )
44 );
45});
有相当多的事情在进行,所以我们来细分一下:
- 首先,我们定义两个模拟用户,我们将针对这些用户进行测试。
- 然后在测试的服务中调用
getData
方法,订阅返回的可观测对象。 - 如果
HttpEventType
是Response
类型,我们断言响应事件的Body与我们的模拟用户相同。 - 然后我们使用
HttpTestingController
(在测试中注入为httpMock
)来断言对服务的url
属性发出了一个请求。如果没有预期的请求,也可以使用expectNone
方法。 - 我们现在可以对模拟请求进行任意数量的断言。这里我们断言请求没有被取消,响应类型为
json
。此外,我们可以断言请求的方法(GET
,POST
,...) - 接下来,我们对模拟请求调用
flush
,并传入模拟用户。flush
方法使用传递给它的数据完成请求。 - 最后,我们在
HttpTestingController
实例上调用verify
方法,以确保没有未完成的请求。
在本教程中,您可以注释掉app.Component.spec.ts
。
通过运行以下命令查看测试结果:
1ng test
在浏览器中打开测试结果:
1[secondary_label Output]
21 spec, 0 failures, randomized with seed 26321
3DataService
4should get users
它将显示一条测试成功的消息。
结论
在本文中,您学习了如何使用HttpClientTestingModule
为HTTP GET请求设置单元测试。
如果你想了解更多关于Angular的知识,请查看我们的Angular主题页面获取练习和编程项目。