Jest 文档说:
Unresolved Promises
If a promise doesn't resolve at all, this error might be thrown:
(等等)
就我而言,这不会发生。 我有这个测试:
test('detect infinite loop', () => {
expect.assertions(1);
const vastPromise = VastUtils.parseFromUrl(infiniteLoopUrl);
const expectedError =
new VastError(VastErrorCodes.WRAPPER_LIMIT_REACHED);
return expect(vastPromise).rejects.toEqual(expectedError);
});
VastUtils
只需获取位于 infiniteLoopUrl
的 XML,对其进行解析,如果此 xml 指向另一个 xml,VastUtils
会点击该链接,解析新的 xml,合并它们并重复该过程。
现在,infiniteLoopUrl
指向引用自身的 XML,因此它是一个无限循环。
“正确地”,代码无限地遵循 xml 链接,并且永远不会解析或拒绝 promise 。
我预计上述测试会在一定的超时后失败,但事实并非如此。
有人可以帮助我吗? 谢谢
编辑: 我正在尝试用一个较小的示例重现无限的 Promise 循环,这就是我注意到的:
此测试在 5 秒后正确失败:
test('Promise2', () => {
const genPromise = (): Promise<void> => {
return new Promise((res) => {
setTimeout(() => {
res();
}, 200);
})
.then(() => {
return genPromise();
});
};
const vastPromise = genPromise();
const expectedError =
new VastError(VastErrorCodes.WRAPPER_LIMIT_REACHED);
return expect(vastPromise).rejects.toEqual(expectedError);
});
此测试在 5 秒后不会失败( Jest 仍处于无限循环中)
test('Promise', () => {
const genPromise = (prom: Promise<void>): Promise<void> => {
return prom
.then(() => {
return genPromise(Promise.resolve());
});
};
const vastPromise = genPromise(Promise.resolve());
const expectedError =
new VastError(VastErrorCodes.WRAPPER_LIMIT_REACHED);
return expect(vastPromise).rejects.toEqual(expectedError);
});
显然这些是相似的,但我不明白导致 Jest 无限循环的区别...
最佳答案
好的,我明白了这个问题。
原因是js的单线程特性。 在编辑部分的两个示例中,第一个示例有超时,因此有时 Jest 会控制并可以检查超时。 在第二个中没有,所对于Jest永远不要检查超时。
在我的真实案例中,问题是假服务器:它的创建方式是:
server = sinon.fakeServer.create({
respondImmediately: true
});
响应立即让sinon同步响应,所以jest永远无法控制。 将其创建为:
server = sinon.fakeServer.create({
autoRespond: true
});
sinon 在 10ms 后响应,jest 可以检查时间流逝
关于testing - 开 Jest , Unresolved promise 不会失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52512949/