【问题标题】:How to catch exception thrown from observable subscription in test如何在测试中捕获从可观察订阅引发的异常
【发布时间】:2019-02-25 05:45:19
【问题描述】:

我不确定如何在 Angular 6 中处理带有 URL 参数的异常。现在,当找不到 URL id 时,我的服务会抛出 Error。在实际应用中,我喜欢错误冒泡以被捕获和记录,但在我的 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)

演示源代码:https://stackblitz.com/edit/angular-observable-catch?file=src%2Fapp%2Fhero%2Fhero-detail.component.spec.ts

如何在我的 jasmine 测试中捕捉到这个错误,以免它导致未捕获的错误?


更新

我发现这是由 AsyncPipe subscription 引起的,它会引发 Observable/Promise/etc 的任何错误。

【问题讨论】:

    标签: angular jasmine observable


    【解决方案1】:

    我发现的解决此问题的方法是将 TestBed 中的 AsyncPipe 替换为不会引发错误的 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();
      }));
    });
    

    【讨论】:

      猜你喜欢
      • 2018-05-01
      • 2011-11-04
      • 2018-08-31
      • 2016-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-25
      • 2018-06-23
      相关资源
      最近更新 更多