I'm trying to unit test my http.get/post/etc responses.
I found this tutorial that was extremely helpful: https://medium.com/spektrakel-blog/angular-testing-snippets-httpclient-d1dc2f035eb8
Going through and following that, I've configured my unit tests and I'm able to get everything working, but there's one part that I have that is inconsistent with the tutorial...
In the tutorial, it shows to test the service login function like this:
it(`should emit 'true' for 200 Ok`, async(inject([HttpClientFeatureService, HttpTestingController],
(service: HttpClientFeatureService, backend: HttpTestingController) => {
service.login('foo', 'bar').subscribe((next) => {
expect(next).toBeTruthy();
});
backend.expectOne('auth/login').flush(null, { status: 200, statusText: 'Ok' });
})));
And here's the actual method on the service that is being tested:
login(user: string, password: string): Observable<boolean> {
const body = new HttpParams()
.set(`user`, user)
.set(`password`, password);
const headers = new HttpHeaders({ 'Content-Type': 'application/x-www-form-urlencoded' });
return this.http.post(`auth/login`, body.toString(), { headers, observe: 'response' })
.map((res: HttpResponse<Object>) => res.ok)
.catch((err: any) => Observable.of(false));
}
Here's my login function:
login(username: string, password: string): Observable<any> {
this.loggingService.log('LoginService | login | username: ' + username + '; password: xxxxx');
return this.http.post(this.loginUrl, { username: username, password: password })
.map((response: any) => {
console.log('response: ' + JSON.stringify(response));
if (response && response.length > 0) {
return response;
} else {
return this.parseErrorResponse(response);
}
});
}
And here's my unit test:
it('login should return a valid JWT', async(inject([LoginService, HttpTestingController], (service: LoginService, backend: HttpTestingController) => {
service.login('user', 'password').subscribe((next) => {
expect(next).toEqual('asdfasdfasdf');
});
backend.expectOne(environment.authenticationServiceBaseUrl + 'api/login')
.flush('asdfasdfasdf', { status: 200, statusText: 'Ok' });
})));
You'll notice the difference here is in the map response section. My version is getting back just a string from the unit test's http.post call, while the example shows that it's returning an HttpResponse object and is just checking that the statusText
property is equal to 'Ok'.
Why is my version returning just the string, while the examples version is returning the actual HttpResponse (which includes status and statusText)? I WANT the tutorial version here...
The example shows that it returns null
in the body of the response via the flush function call, while I had to add my dummy JWT value in there in order to get my test to pass. Even when I specify that as null
to be like the test, then the response that I get in the unit test is null
.
Where am I going wrong here?
The tutorial uses observe: 'response'
, which means that events emitted by the returned observable are responses, and not just the body.
This is covered in the http guide.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With