【发布时间】: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 帖子,我尝试使用 async、async(done) => done()、fakeAsync,但似乎没有任何效果。我总是收到以下错误:
超时 - 在 jest.setTimeout.Error 指定的 5000 毫秒超时内未调用异步回调:超时 - 在 jest.setTimeout 指定的 5000 毫秒超时内未调用异步回调。
注意:我正在为响应注入 MockInterceptor,并且服务正在使用 RxJs timer() 可观察的轮询,我可以确认它在测试结束时已关闭并取消订阅,这已由expect(service.isPolling) 代码行。我曾尝试使用 jest.userRealTimers 和 jest.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