关于angular:与RXJS catchError一起使用时,预期抛出的实际崩溃

Expect to throws actually crashes when used with RXJS catchError

1
2
3
4
5
6
7
8
9
10
11
12
it('minimal test case', () => {
    expect(() => {
        of(1).pipe(
            map(() => {
                throw new Error('err');
            }),
            catchError(() => {
                throw new Error('new err');
            }),
        ).subscribe();
    }).toThrow();
});

即使在原始的Error堆栈跟踪中导致catchError内部的Error,该代码实际上也会使Jasmine / Karma的整个执行崩溃。

我认为,如果可观察的抛出并无法处理,则应在其所处的上下文中传播该错误。否则,我无法测试可观察的抛出。

此(茉莉花)测试将产生以下错误:

Uncaught Error: new err
at CatchSubscriber.selector (slideshow.directive.spec.ts:224)
at CatchSubscriber.push.../../node_modules/rxjs/_esm5/internal/operators/catchError.js.CatchSubscriber.error
(catchError.js:34)
at MapSubscriber.push.../../node_modules/rxjs/_esm5/internal/operators/map.js.MapSubscriber._next
(map.js:38)
at MapSubscriber.push.../../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next
(Subscriber.js:53)
at Observable._subscribe (subscribeToArray.js:5)
at Observable.push.../../node_modules/rxjs/_esm5/internal/Observable.js.Observable._trySubscribe
(Observable.js:43)
at Observable.push.../../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe
(Observable.js:29)
at MapOperator.push.../../node_modules/rxjs/_esm5/internal/operators/map.js.MapOperator.call
(map.js:18)
at Observable.push.../../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe
(Observable.js:24)
at CatchOperator.push.../../node_modules/rxjs/_esm5/internal/operators/catchError.js.CatchOperator.call
(catchError.js:18)

TypeError: Cannot read property 'error' of undefined
at directCallParentKarmaMethod (context.js:270)
at ContextKarma.error (context.js:155)
at handleGlobalErrors (adapter.js:176)
at KarmaReporter.suiteDone (adapter.js:224)
at dispatch (jasmine.js:4560)
at ReportDispatcher.suiteDone (jasmine.js:4531)
at nodeComplete (jasmine.js:1019)
at onComplete (jasmine.js:5528)
at ZoneDelegate.../../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask
(zone.js:423)
at Zone.../../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:195)

Expected function to throw an exception.
at UserContext. (http://localhost:9876/src/app/shared/thumbnail/slideshow.directive.spec.ts?:227:6)
at ZoneDelegate.../../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke
(http://localhost:9876/C:/Users/uzivatel/Documents/nubium/ulozto-web/angular/node_modules/zone.js/dist/zone.js?:391:1)
at ProxyZoneSpec.push.../../node_modules/zone.js/dist/zone-testing.js.ProxyZoneSpec.onInvoke
(http://localhost:9876/C:/Users/uzivatel/Documents/nubium/ulozto-web/angular/node_modules/zone.js/dist/zone-testing.js?:289:1)
at ZoneDelegate.../../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke
(http://localhost:9876/C:/Users/uzivatel/Documents/nubium/ulozto-web/angular/node_modules/zone.js/dist/zone.js?:390:1)


一种可能的解决方案是将错误重定向到成功路径,然后测试该值。 当被测流的逻辑连接到引发不同的错误类型时,这将很有用(尽管在这种情况下,对instanceof Error的测试当然是不够的)。

1
2
3
4
5
6
7
8
9
10
11
  it('should be of type error', () => {
    of(1)
      .pipe(
        map(() => {
          throw new Error('err');
        }),
        catchError(error => of(error)))
      .subscribe(result => {
        expect(result instanceof Error).toBe(true);
      });
  });

但是,更常见的方法afaik是测试是否调用了正确的回调,如JB Nizet所述。 例如。 您的服务具有handleError方法,当流错误时应调用该方法。