Canemacchina
Canemacchina

Reputation: 179

Jest unresolved promise do not fail

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

Answers (1)

Canemacchina
Canemacchina

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

Related Questions