【问题标题】:Angular test with `async` causing Jasmine timeout?使用“异步”进行角度测试导致 Jasmine 超时?
【发布时间】:2018-06-07 17:56:50
【问题描述】:

我最近将一个项目升级到 Angular 6,现在之前运行良好的测试现在失败了。以下是其中一项测试的示例:

  beforeEach(
    async(() => {
      TestBed.configureTestingModule({
        declarations: [CampaignsDetailScheduleComponent],
        imports: [
          SomeModule,
          ReactiveFormsModule,
          TranslateModule.forRoot({
            loader: { provide: TranslateLoader, useClass: TranslateFakeLoader }
          }),
          StoreModule.forRoot({})
        ],
        providers: [{ provide: ConfigService, useValue: ConfigServiceMock }],
        schemas: [NO_ERRORS_SCHEMA]
      });
      fixture = TestBed.createComponent(CampaignsDetailScheduleComponent);
      comp = fixture.componentInstance; // Component test instance
      _store = fixture.debugElement.injector.get<Store<State>>(Store);
      comp.campaignModel$ = of(CampaignMockData);
      fixture.detectChanges();
    })
  );

it(
    'close edit schedule modal',
    async(() => {
      spyOn(_store, 'dispatch');
      comp.onClose();
      const args = new ShowHideEditScheduleModal(false);
      expect(_store.dispatch).toHaveBeenCalledWith(args);
    })
  );

在 Angular 6 之前,此测试通过,没有任何问题。但是现在在 Angular 6 下,我得到了错误:

Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.--Pendng async tasks are: [type: macroTask, source: setInterval, args: {handleId:4072,isPeriodic:true,delay:0,args:[object Arguments],__creationTrace__:[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]},type: macroTask, source: setInterval, args: {handleId:4075,isPeriodic:true,delay:0,args:[object Arguments],__creationTrace__:[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]}]

有人知道会发生什么吗?

【问题讨论】:

  • 我不知道这是不是 Jasmine 的东西,但是你确定你需要 async,因为你没有任何 await 吗?
  • @Seblor 在这种情况下,async 不是 JavaScript 的 async 关键字,它是 Angular 提供的辅助函数。
  • 感谢您的信息。你有关于那个文档的链接吗?
  • 你试过这个修复吗? github.com/angular/protractor/issues/…

标签: javascript angular typescript jasmine


【解决方案1】:

在每个块之前使用fakeAsync 而不是async

【讨论】:

    【解决方案2】:

    您可以通过这样做来增加默认的 jasmine 超时(即 5 秒)间隔

    it(
        'close edit schedule modal',
        async(() => {
          spyOn(_store, 'dispatch');
          comp.onClose();
          const args = new ShowHideEditScheduleModal(false);
          expect(_store.dispatch).toHaveBeenCalledWith(args);
       // increase default timeout interval to 10s
    }), 10000);
    

    或者您可以使用done() 方法解决它。添加这将等待您的测试完成。我猜你在使用done()时不能使用async

    it('close edit schedule modal', (done) => {
              spyOn(_store, 'dispatch');
              comp.onClose();
              const args = new ShowHideEditScheduleModal(false);
              expect(_store.dispatch).toHaveBeenCalledWith(args);
              done();
           // increase default timeout interval to 10s
     }, 10000);
    

    【讨论】:

    • 感谢您的建议。不幸的是,在这种情况下,这些解决方案似乎都不起作用。 :(
    • 好的 comp.onClose(); 异步执行正确。然后您可以简单地在setTimeout() 中添加代码。或者,如果您想坚持使用async,请使用fixture.whenStable().then()
    • 真正奇怪的是,我在其他文件中还有其他遵循相同模式的测试,并且这些测试通过了。我不知道这里发生了什么。
    • 我能够缩小问题范围。如果我在beforeEach 调用中注释掉对fixture.detectChanges() 的调用,则测试通过。不知道为什么,虽然......
    • 那么,您可能在ngOnInit() 中有一些异步的东西。由于您注释掉了fixture.detectChanges,因此您的ngOnInit() 未被调用,因此您的测试用例同步执行,使其通过。
    猜你喜欢
    • 1970-01-01
    • 2013-06-28
    • 2013-06-27
    • 2014-09-23
    • 2020-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-26
    相关资源
    最近更新 更多