How To Test HttpClient Requests in Angular
source link: https://www.digitalocean.com/community/tutorials/angular-testing-httpclient
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Introduction
Angular’s HttpClient
has a testing module, HttpClientTestingModule
, that makes it possible for you to unit test HTTP requests.
Note: Since HttpClient
is available only starting with Angular 4.3, the following applies to Angular 4.3+. Consult this introduction if you’re new to unit testing in Angular.
In this article, you will learn how to set up unit tests for an HTTP GET request using the HttpClientTestingModule
. This will help demonstrate the capabilities of the testing module.
Prerequisites
To complete this tutorial, you will need:
This tutorial was verified with Node v16.2.0, npm
v7.15.1, and @angular/core
v12.0.4.
Step 1 — Setting Up the Project
For this post, we’ll be working with a service that gets data from an endpoint and a component that calls that service to populate a list of users in the component’s OnInit
hook.
You can use @angular/cli
to create a new project:
ng new angular-httpclienttest-example
Then, navigate to the newly created project directory:
cd angular-httpclienttest-example
Create a data.service.ts
:
ng generate service data
And have it communicate with 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);
}
}
Then, modify the app.component.ts
file:
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;
}
});
}
}
And add the HttpClientmodule
to 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 { }
At this point, you will have an Angular project with a service and client.
Step 2 — Adding Tests
Now we’ll setup a spec file for our data service and include the necessary utilities to test out the HttpClient
requests. On top of HttpClientTestingModule
, we’ll also need HttpTestingController
, which makes it easy to mock requests:
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);
});
});
We use the inject
utility to inject the needed services into our test.
With this in place, we can add our test logic:
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();
}
)
);
});
There’s quite a bit going on, so let’s break it down:
- First we define a couple of mock users that we’ll test against.
- We then call the
getData
method in the service that we’re testing and subscribe to returned observable. - If the
HttpEventType
is of typeResponse
, we assert for the response event to have a body equal to our mock users. - We then make use of the
HttpTestingController
(injected in the test ashttpMock
) to assert that one request was made to the service’surl
property. If no request is expected, theexpectNone
method can also be used. - We can now make any number of assertions on the mock request. Here we assert that the request hasn’t been canceled and the response is of type
json
. Additionally, we could assert the request’s method (GET
,POST
, …) - Next we call
flush
on the mock request and pass in our mock users. Theflush
method completes the request using the data passed to it. - Finally, we call the
verify
method on ourHttpTestingController
instance to ensure that there are no outstanding requests to be made.
For the purposes of this tutorial, you can comment out app.component.spec.ts
.
See the result of your testing by running the following command:
ng test
Open the test results in the browser:
Output
1 spec, 0 failures, randomized with seed 26321
DataService
should get users
It will display a successful test message.
Conclusion
In this article, you learned how to set up unit tests for an HTTP GET request using the HttpClientTestingModule
.
If you’d like to learn more about Angular, check out our Angular topic page for exercises and programming projects.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK