Angular Tests随机打破:"Uncaught TypeError:你提供了'undefined',预计会有一个流."

Ale*_*KER 10 jasmine rxjs karma-jasmine

我们有一个中等角度的应用程序,目前约有700个单元测试.几个星期前,完美的测试开始破裂.更奇怪的是:两次运行测试会产生不同的结果,即不同的测试可能会中断.在控制台中,我们总能找到错误:

未捕获的TypeError:您在预期的流中提供了"未定义".

但是堆栈跟踪没有提示错误的根实际位于何处(参见本文末尾).堆栈跟踪显示了与mergeMap操作员的连接,但事实证明我们在我们的应用程序中没有使用此运算符,在我们的测试中没有任何地方.

我逐步浏览了所有的spec文件,让它们自己运行(带fdescribe).每个spec文件都没有错误地传递.将它们一起运行会导致所描述的破损.

当然我的猜测是我们遇到了一个异步问题所以我花了很多精力去完成所有的测试并将它们中的每一个都包装在一个异步环境中.我还检查了每个订阅在某些时候都取消订阅 - 这是我们的应用程序的情况,但并不总是我们的测试.但是,错误仍然存​​在.

这对我们的项目来说是个大问题.任何建议都非常欢迎.也许有人知道找到引起问题的测试部分的方法?

我们现在使用jasmine 3.3.0,karma v3.1.4和Angular 7.1.3.我们在一周前做了茉莉和角的更新,因为我们希望摆脱这个问题.只有一件事情发生了变化:在更新之前,测试并没有随机破坏,而是在固定数量的测试中(在我们的例子中,639次测试会导致测试中断,638,640,641 ......会通过; 648会再次破裂).我认为它与茉莉花现在使用的随机种子有关.

这是完整的堆栈跟踪:

<!-- language: lang-none -->
Uncaught TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
    at subscribeTo (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/util/subscribeTo.js:41)
    at subscribeToResult (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/util/subscribeToResult.js:11)
    at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber._innerSub (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/operators/mergeMap.js:74)
    at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber._tryNext (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/operators/mergeMap.js:68)
    at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber._next (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/operators/mergeMap.js:51)
    at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/Subscriber.js:54)
    at Observable._subscribe (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/util/subscribeToArray.js:5)
    at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable._trySubscribe (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/Observable.js:43)
    at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/Observable.js:29)
    at MergeMapOperator.push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapOperator.call (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/operators/mergeMap.js:29)
    at ____________________Elapsed_3_ms__At__Thu_Dec_27_2018_10_03_35_GMT_0100__Mitteleurop_ische_Normalzeit_ ()
    at Object.onScheduleTask (:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-testing.js:108)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask (:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:401)
    at Object.onScheduleTask (:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:297)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask (:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:401)
    at Zone.push../node_modules/zone.js/dist/zone.js.Zone.scheduleTask (:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:232)
    at Zone.push../node_modules/zone.js/dist/zone.js.Zone.scheduleMacroTask (:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:255)
    at scheduleMacroTaskWithCurrentZone (:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:1114)
    at :9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:2090
Run Code Online (Sandbox Code Playgroud)

Bjo*_*' S 3

噢,听起来事情变得不稳定了。最近我们遇到了单元测试随机中断的情况。您是否一直在更新 Angular 和 Karma 版本?

我们遇到的问题是,默认设置单元测试的方式(通过 Angular CLI)已经改变,并且旧的测试没有以正确的async方式运行。

您看到的错误确实与我们看到的不同,但我确信这是一个值得探索的途径,可以消除单元测试设置引入的任何脆弱性。

取自https://angular.io/guide/testing#calling-compilecomponents

describe('BannerComponent', () => {
    let component: BannerComponent
    let fixture: ComponentFixture<BannerComponent>

    beforeEach(async(() => {
      TestBed.configureTestingModule({
        declarations: [ BannerComponent ],
      }).compileComponents();  // compile template and css
    }));

    beforeEach(() => {
        fixture = TestBed.createComponent(BannerComponent)
        component = fixture.componentInstance
        fixture.detectChanges()
    })

    it('should create', () => {
        expect(component).toBeTruthy()
    })
Run Code Online (Sandbox Code Playgroud)

特别注意第一个beforeEach(),其中有一个async() => {},并且有一个必需的.compileComponent()

第二个是在 的共享上下文中beforeEach()定义和填充变量。componentdescribe()

我希望这可以帮助您找出导致片状现象的原因。由于源自 RxJS 的迭代器问题似乎指向依赖于先前测试设置的状态的测试,其中它接收 Observable 形式的输入。如果此 Observable 是在测试执行之后设置或定义的,那么您可能会遇到与您所描述的问题类似的问题。