【发布时间】:2019-06-19 08:23:34
【问题描述】:
我有一个组件,它最终通过连续的switchMap 调用一堆 HTTP 服务来从后端获取数据。
我想测试错误处理部分。该应用程序具有全局错误处理 (ErrorHandler) 和通过 catchError 进行的本地错误处理。
测试方法如下:
public methodUsingObservable() {
this.someRequest()
.pipe(catchError((error) => this.handleError(error)))
.subscribe(console.log);
}
如果错误链接到业务操作,则处理错误检查,并再次抛出以由全局处理程序处理
handleError(error) {
checkLocally(error);
return throwError(error);
}
对于我的测试,我用throwError 模拟someRequest 来模拟后端调用的问题
it('should handle the error when one occurs', fakeAsync(() => {
const service: MachinService = TestBed.get(MachinService);
spyOn(service,'someRequest').and.returnValue(throwError(new Error("Failing HTTP call")));
spyOn(service,'handleError').and.callThrough();
service.methodUsingObservable();
tick();
expect(service.methodUsingObservable).toThrowError();
expect(service.handleError).toHaveBeenCalled();
}));
但是,无论我如何监视和期待某事,Karma 都会一直认为测试失败,因为订阅正如实际预期的那样抛出了未处理的错误。
我试过了:
expect(service.methodUsingObservable).toThrowError();
expect(service.methodUsingObservable()).toThrowError();
expect(() => service.methodUsingObservable()).toThrowError();
但似乎没有人教系统接受测试成功,而测试失败。
Chrome 62.0.3202 (Windows 10.0.0) MachinService should handle the error when one occurs FAILED
Error: Failing HTTP call
at UserContext.<anonymous> src/app/shared/services/machin.service.spec.ts:12:64)
...
如何在这些条件下将测试标记为通过?
【问题讨论】:
-
您实际上是在正确处理错误,但您的订阅最终没有捕捉到它。尝试将空错误回调作为第二个参数添加到您的订阅:
.subscribe(console.log, () => {}); -
如果你能在某个地方创建一个演示,我会自己尝试一下
-
另外我认为你不需要
fakeAsync和tick() -
此时未捕获错误是想要的实际行为,核心应用程序希望使用全局
MyExceptionHandler implements ErrorHandler捕获所有异常。在订阅中添加错误回调,错误不会到Handler。我添加了一个 catchError 来拦截任何可识别的业务异常并向用户显示一条消息,但随后错误继续 -
您能确认您使用的是 Jasmine 版本 3.* 吗?
标签: angular unit-testing rxjs karma-jasmine