与RXJS catchError

时间:2019-07-03 14:43:35

标签: angular unit-testing rxjs jasmine karma-jasmine

it('minimal test case', () => {
    expect(() => {
        of(1).pipe(
            map(() => {
                throw new Error('err');
            }),
            catchError(() => {
                throw new Error('new err');
            }),
        ).subscribe();
    }).toThrow();
});

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

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

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

  

未捕获的错误:新错误       在CatchSubscriber.selector(slideshow.directive.spec.ts:224)       在CatchSubscriber.push ... / .. / node_modules / rxjs / _esm5 / internal / operators / catchError.js.CatchSubscriber.error   (catchError.js:34)       在MapSubscriber.push ... / .. / node_modules / rxjs / _esm5 / internal / operators / map.js.MapSubscriber._next   (map.js:38)       在MapSubscriber.push ... / .. / node_modules / rxjs / _esm5 / internal / Subscriber.js.Subscriber.next   (Subscriber.js:53)       在Observable._subscribe(subscribeToArray.js:5)       在Observable.push ... / .. / node_modules / rxjs / _esm5 / internal / Observable.js.Observable._trySubscribe   (Observable.js:43)       在Observable.push ... / .. / node_modules / rxjs / _esm5 / internal / Observable.js.Observable.subscribe   (Observable.js:29)       在MapOperator.push ... / .. / node_modules / rxjs / _esm5 / internal / operators / map.js.MapOperator.call   (map.js:18)       在Observable.push ... / .. / node_modules / rxjs / _esm5 / internal / Observable.js.Observable.subscribe   (Observable.js:24)       在CatchOperator.push ... / .. / node_modules / rxjs / _esm5 / internal / operators / catchError.js.CatchOperator.call   (catchError.js:18)

     

TypeError:无法读取未定义的属性“错误”       在directCallParentKarmaMethod(context.js:270)       在ContextKarma.error(context.js:155)       在handleGlobalErrors(adapter.js:176)       在KarmaReporter.suiteDone(adapter.js:224)       派遣时(jasmine.js:4560)       在ReportDispatcher.suiteDone(jasmine.js:4531)       在nodeComplete(jasmine.js:1019)       在onComplete(jasmine.js:5528)       在ZoneDelegate ... / .. / node_modules / zone.js / dist / zone.js.ZoneDelegate.invokeTask   (zone.js:423)       在Zone ... / .. / node_modules / zone.js / dist / zone.js.Zone.runTask(zone.js:195)

     

期望的函数引发异常。       在UserContext上。 (http://localhost:9876/src/app/shared/thumbnail/slideshow.directive.spec.ts?:227:6)       在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)       在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)       在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

1 个答案:

答案 0 :(得分:1)

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

  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方法,当流错误时应调用该方法。