Jasmine HTTP测试未覆盖RXJS管道

时间:2019-02-06 18:45:53

标签: angular unit-testing http jasmine rxjs

问题

大家好,我在Angular 2项目中添加了一些Karma-Jasmine单元测试,但我终生无法获得服务方法中的RXJS运算符。

测试使用的是HttpClientTestingModule和HttpTestingController。

代码

这是一个仅使用map运算符的简单示例。

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

我本以为在测试中订阅可观察对象会触发 map()调用,但也许我误会了这些模拟服务的工作原理。

从周围看,似乎切换到 XHRBackend 而不是HttpClientTestingModule来生成虚拟200/404 / etc响应可以解决此问题,但是除了更多样板外,大多数人似乎建议改用TestingModule。

1 个答案:

答案 0 :(得分:3)

尝试将flush()和其他测试逻辑移到订阅之外,只将Expect(response)留在里面。像这样:

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