Hey everyone, I'm adding some Karma-Jasmine unit-testing to my Angular 2 project and I cannot for the life of me get the coverage to hit the RXJS operators in my service methods.
The tests are using the HttpClientTestingModule and HttpTestingController.
Here's a simple example just using the map operator.
MyService:
getAssetCount(): Observable<AssetModel[]> {
return this.http
.get('/myproject/v1/asset-count')
.pipe(map(response => response as AssetModel[]));
}
MyService.spec:
service = testBed.get(MyService);
httpMock = testBed.get(HttpTestingController);
...
it('should getAssetCount', () => {
const dummyResponse = [{...}];
service.getAssetCount().subscribe((response: AssetModel[]) => {
expect(response).toEqual(dummyResponse);
const req = httpMock.expectOne(
'/myproject/v1/asset-count'
);
expect(req.request.method).toBe('GET');
req.flush(dummyResponse);
httpMock.verify();
});
});
The resulting coverage:
I would have thought having a subscription to the observable in the test would trigger the map() call, but perhaps I'm misunderstanding how these mock services work.
From looking around, it seems like switching to the XHRBackend instead of the HttpClientTestingModule to generate dummy 200/404/etc responses could solve the issue, but besides being more boilerplate, it seems like most people were suggesting to use the TestingModule instead.
To enable this, open the Karma test platform configuration file, karma. conf. js , and add the check property in the coverageReporter: key. The check property causes the tool to enforce a minimum of 80% code coverage when the unit tests are run in the project.
detectChanges() tells Angular to run change-detection. Finally! Every time it is called, it updates data bindings like ng-if, and re-renders the component based on the updated data. Calling this function will cause ngOnInit to run only the first time it is called.
Try moving the flush()
and other testing logic outside of the subscribe, just leaving the expect(response) inside. Something like this:
it('should getAssetCount', () => {
const dummyResponse = [{...}];
service.getAssetCount().subscribe((response: AssetModel[]) => {
expect(response).toEqual(dummyResponse);
});
const req = httpMock.expectOne(
'/myproject/v1/asset-count'
);
expect(req.request.method).toBe('GET');
req.flush(dummyResponse);
httpMock.verify();
});
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