【问题标题】:Jest - Async callback was not invoked within the 5000 ms timeout specified by jest.setTimeout.ErrorJest - 在 jest.setTimeout.Error 指定的 5000 毫秒超时内未调用异步回调
【发布时间】:2021-05-13 08:45:38
【问题描述】:

我可以看到在 SO 上有很多关于此的问题,但没有一个回答我的问题。

我有以下测试

 it('will poll until there are no subscribers', () => {
    const polls: string[] = [];
    const complete = new Subject<void>();
    const observableSub = service
      .getPollData()
      .pipe(takeUntil(complete))
      .subscribe((value) => {
        polls.push(value);
        if (polls.length === 3) {
          console.log('here ' + JSON.stringify(polls));
          observableSub.unsubscribe();
          complete.next();
          complete.complete();
        }
      });

    return complete.toPromise().then(() => {
      console.log(service.isPolling);
      expect(service.isPolling).toEqual(false);
    });
  });

当测试运行时,我的两个控制台日志都存在并且具有正确的预期值。这一切都发生在 20 毫秒内,我的轮询频率设置为仅 5 毫秒进行测试。

我查看了我能找到的所有 SO 帖子,我尝试使用 asyncasync(done) =&gt; done()fakeAsync,但似乎没有任何效果。我总是收到以下错误:

超时 - 在 jest.setTimeout.Error 指定的 5000 毫秒超时内未调用异步回调:超时 - 在 jest.setTimeout 指定的 5000 毫秒超时内未调用异步回调。

注意:我正在为响应注入 MockInterceptor,并且服务正在使用 RxJs timer() 可观察的轮询,我可以确认它在测试结束时已关闭并取消订阅,这已由expect(service.isPolling) 代码行。我曾尝试使用 jest.userRealTimersjest.useFakeTimers 以防这是问题的一部分,但我的控制台日志显示预期值的事实让我认为这不是问题。

任何帮助将不胜感激。

*按照@Estus Flask 的建议更新我现在已将代码更新为:

it('will poll until there are no subscribers', async () => {
      const polls: any[] = [];
      const observableSub = service.getPollData().pipe(
      take(3),
      tap((value) => {
        polls.push(value);
      })
    );
      await observableSub.toPromise().then(() => {
      console.log(JSON.stringify(polls));
      console.log(service.isPolling);
      expect(service.isPolling).toEqual(false);
    });
 });

但仍然出现同样的错误,感觉我正在做/错过一些简单而愚蠢的事情?!?!?注意:控制台输出仍然是正确的。

【问题讨论】:

  • Observables 以一种笨拙的方式交互,并且不处理错误。 complete 是多余的,它可能没有竞争,这导致未决的承诺,不能确切地说出原因。应该只有一个 observable,可能是 take(3),使用 toPromise 就可以了。和await它。
  • @Estus Flask 感谢您的建议,我已更改为您建议的(我认为)仍然遇到相同的错误:/ 非常令人沮丧。
  • take(3) 导致完成的 observable 并转换为已解决的承诺,因此它不会导致此错误。那么解释是小于3个值,或者错误指向另一个块,不一定是it
  • @EstusFlask 是的,正如我提到的,所有控制台输出都是预期值,包括 3 次投票,service.isPolling == false,这很奇怪。我相信该服务已经清理了它的 RxJsTimer 并且也取消订阅了
  • @EstusFlask,解决了,看看我的答案!

标签: angular typescript jestjs angular-test


【解决方案1】:

如果其他人遇到此问题,值得看看您在测试集中的其他测试。

事实证明,对我来说,上面的测试通过了,但是随后的带有 setTimeout 的测试失败了。这让 Jest 感到困惑,然后将通过测试标记为失败!

我在这方面浪费了很多时间,所以希望这对未来的人有所帮助。

【讨论】:

    【解决方案2】:

    你试过用 done 吗?

    it('will poll until there are no subscribers', async (done) => {
          const polls: any[] = [];
          const observableSub = service.getPollData().pipe(
          take(3),
          tap((value) => {
            polls.push(value);
          })
        );
          await observableSub.toPromise().then(() => {
          console.log(JSON.stringify(polls));
          console.log(service.isPolling);
          expect(service.isPolling).toEqual(false);
          done()
        });
     });
    

    【讨论】:

      猜你喜欢
      • 2019-03-11
      • 2020-05-13
      • 2018-09-18
      • 2018-09-11
      • 2019-04-23
      • 2018-12-05
      • 2020-01-15
      • 2020-12-09
      相关资源
      最近更新 更多