大家好,我正在向我的 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。
更改页面时取消挂起的 HTTP 请求
我们有一个 Angular 服务,它有一个昂贵的 HTTP 查询,可供 3 个不同的消费者访问。每个消费者都可以随时修改此查询,发出新请求,并且所有其他消费者都必须使用新数据进行更新。
因为 HTTP 订阅在完成后立即关闭,所以我们使用带有行为主体的内部可观察模式来保持消费者的连接(见下文)。
那么问题是,当用户更改页面时,当前挂起的 HTTP 响应无法取消。
通常,我认为在后台丢弃 HTTP 请求不会有太大问题……但除了这是一项昂贵的操作之外,我发现在用户返回后是否确实解决了挂起的响应到页面,它将使用旧查询的数据更新消费者。
没有布埃诺。
private dataSubject = new BehaviorSubject<MyData>(...);
public data$ = this.dataSubject.asObservable();
...
getData(): Observable<MyData> {
if (this.dataSubject)
return this.data$;
} else {
const http$ = this.http.post(...))
.pipe(map(response => response as MyData),
takeUntil(this.unsubscribe$)); // see tearDown() below
http$.subscribe(
(availableDevices: MyData) => {
this.dataSubject.next(availableDevices);
}
);
return this.data$;
}
}
Run Code Online (Sandbox Code Playgroud)
我试图在每个消费者在 ngDestroy() 期间调用的服务中创建一个拆卸方法,但除非我完成了流,否则它不起作用。但那时,当用户返回页面时,我无法再次重新启动流。
tearDown(): void {
this.unsubscribe$.next();
this.unsubscribe$.complete();
// this.dataSubject.next(null);
// this.dataSubject.complete(); -- …Run Code Online (Sandbox Code Playgroud)