如何在 Angular 中测试 HttpClient 请求

简介

Angel的HttpClient有一个测试模块HttpClientTestingModule,,它使您能够对HTTPS请求进行单元测试。

<$>[注] 注意: 由于HttpClient仅从Angular 4.3开始可用,因此以下内容适用于Angular 4.3+。如果你是Angular单元测试的新手,请参考这篇介绍。 <$>

在本文中,您将了解如何使用HttpClientTestingModule为HTTP GET请求设置单元测试。这将有助于演示测试模块的功能。

预约

要完成本教程,您需要:

本教程已经在Node v16.2.0、npmv7.15.1和@angular/corev12.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方法,订阅返回的可观测对象。
  • 如果HttpEventTypeResponse类型,我们断言响应事件的Body与我们的模拟用户相同。
  • 然后我们使用HttpTestingController(在测试中注入为httpMock)来断言对服务的url属性发出了一个请求。如果没有预期的请求,也可以使用expectNone方法。
  • 我们现在可以对模拟请求进行任意数量的断言。这里我们断言请求没有被取消,响应类型为json。此外,我们可以断言请求的方法(GETPOST,...)
  • 接下来,我们对模拟请求调用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主题页面获取练习和编程项目。

Published At
Categories with 技术
Tagged with
comments powered by Disqus