angular - 如何在测试中捕获从可观察订阅引发的异常
问题描述
我不确定如何在 Angular 6 中使用 URL 参数处理异常。现在,Error
当找不到 URL id 时,我的服务会抛出一个异常。在实际的应用程序中,我喜欢错误冒泡以被捕获和记录,但在我的 jasmine 测试中导致测试失败:
HeroDetailComponent should navigate to not found page
[object ErrorEvent] thrown
我已经尝试了各种try {} catch () {}
块和catchError
管道来处理 jasmine 中的错误,但在测试预期运行之后似乎没有任何东西能够捕捉到这个错误。
问题演示:https ://angular-observable-catch.stackblitz.io/
请注意,在 stackblitz 上,测试不会失败,但在我的应用程序中使用ng test
.
在(主)控制台中注意错误:
Uncaught Error: Hero 999 not found.
at HeroService.getHeroById (hero.service.ts:33)
at SwitchMapSubscriber.eval [as project] (hero-detail.component.ts:46)
at SwitchMapSubscriber._next (switchMap.ts:103)
at SwitchMapSubscriber.Subscriber.next (Subscriber.ts:104)
at ReplaySubject.Subject.next (Subject.ts:62)
at ReplaySubject.nextInfiniteTimeWindow (ReplaySubject.ts:42)
at ActivatedRouteStub.setParamMap (activated-route-stub.ts:56)
at UserContext.eval (hero-detail.component.spec.ts:65)
at ZoneDelegate.invoke (zone.js:388)
at ProxyZoneSpec.onInvoke (zone-testing.js:288)
如何在我的 jasmine 测试中捕获此错误,以免导致未捕获错误?
更新
我发现这是由AsyncPipe 订阅引起的,它会抛出 Observable/Promise/etc 的任何错误。
解决方案
我为这个问题找到的一种解决方法是用不会引发错误的 AsyncPipe 替换 TestBed 中的 AsyncPipe。
测试异步管道.ts:
import { AsyncPipe } from '@angular/common';
import { Pipe } from '@angular/core';
/**
* When the AsyncPipe throws errors Jasmine cannot catch them and causes tests to fail.
* For tests just log the error and move on.
* Add this class to the TestBed.configureTestingModule declarations.
*/
@Pipe({name: 'async', pure: false}) // tslint:disable-line:use-pipe-transform-interface
export class TestAsyncPipe extends AsyncPipe {
transform(obj: any): any {
const ret = super.transform(obj);
const handleError = (err: any) => { console.error('AsyncPipe Template Exception', err); };
// @ts-ignore: patch the Observable error handler to not throw an error in tests.
this._subscription.destination._error = handleError;
// What if the subscription is a Promise?
return ret;
}
}
a-test.spec.ts
import { async, TestBed } from '@angular/core/testing';
import { TestAsyncPipe } from '../testing/test-async-pipe';
import { TestComponent} from './test.component';
describe('TestComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ TestAsyncPipe, TestComponent],
})
.compileComponents();
}));
});
推荐阅读
- android - getAllCellInfo() returns null android API Level 28.how to solve this?
- javascript - 如何解决错误:邮递员中的套接字挂起
- java - 打开锁 - BFS 应用程序
- java - ASM TraceClassVisitor 输出文件错误
- kubernetes - 如何在 Helm Chart 中使用 Lookup 功能
- reactjs - 仅将两个背景色放在两行上
- r - 如何从mac终端打开不同的R版本?
- google-api-java-client - 您如何将谷歌地理编码和时区 API 与官方 Java 库一起使用?
- react-native - React-Navigation useIsFocused 总是返回 true,我不知道为什么?
- azure-devops - Azure Devops:当管道生成新工件时,继续部署不会触发