Jasmine HTTP 测试未覆盖 RXJS 管道

Rob*_*Lee 6 unit-testing http jasmine rxjs angular

问题

大家好,我正在向我的 Angular 2 项目添加一些 Karma-Jasmine 单元测试,但我一生都无法在我的服务方法中覆盖 RXJS 操作员。

测试使用 HttpClientTestingModule 和 HttpTestingController。

代码

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

我的服务:

getAssetCount(): Observable<AssetModel[]> {
  return this.http
    .get('/myproject/v1/asset-count')
    .pipe(map(response => response as AssetModel[]));
}
Run Code Online (Sandbox Code Playgroud)

我的服务规范:

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();
  });
});
Run Code Online (Sandbox Code Playgroud)

结果

由此产生的覆盖范围:

由此产生的覆盖范围

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

环顾四周,似乎切换到XHRBackend而不是 HttpClientTestingModule 来生成虚拟 200/404/etc 响应可以解决该问题,但除了更多样板之外,似乎大多数人都建议使用 TestingModule。

dmc*_*dle 5

尝试将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();
});
Run Code Online (Sandbox Code Playgroud)