Robert Lee
Robert Lee

Reputation: 165

Jasmine HTTP tests not getting coverage on RXJS pipeline

Problem

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.

Code

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();
  });
});

Result

The resulting coverage:

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.

Upvotes: 6

Views: 1647

Answers (1)

dmcgrandle
dmcgrandle

Reputation: 6060

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();
});

Upvotes: 5

Related Questions