Reputation: 179
Jest docs says:
Unresolved Promises
If a promise doesn't resolve at all, this error might be thrown:
(and so on)
In my case this not happen. I have this test:
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
simply fetch an XML located at infiniteLoopUrl
, parse it, and if this xml point to another xml, VastUtils
follow the link, parse the new xml, merge them and repeat the process.
Now, infiniteLoopUrl
point to an XML that refers itself, so it is an infinite loop.
"correctly", the code follow xml link infinitely, and never resolve or reject the promise.
I expect above test fail after a certain timeout, but it didn't.
Someone can help me? Thanks
EDIT: I'm trying to reproduce an infinite Promise loop with a smaller example, and this is what i've noticed:
this test correctly FAIL after 5s:
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);
});
This test DO NOT FAIL after 5s (jest remain in an infinite loop)
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);
});
Apparently these are similar, but I don't understand the difference that cause the jest infinite loop...
Upvotes: 2
Views: 1190
Reputation: 179
Ok, I've understand the problem.
The cause is the mono thread nature of js. In the two examples of the edit section, te first one have a timeout so there is a moment whent jest take the control and could check the timeout. In the second one no, so jest never check the timeout.
In my real case, the problem was the fake server: it was created as:
server = sinon.fakeServer.create({
respondImmediately: true
});
respondImmediately make sinon respond syncroniously, so jest never have the control. Creating it as:
server = sinon.fakeServer.create({
autoRespond: true
});
sinon respond after 10ms and jest can check the time passing
Upvotes: 2