Reputation: 249
Trying to do a relatively simple assertion with jest. I have the following test setup:
const sleep = ms => new Promise(res => setTimeout(res, ms));
it('should call callback after specified delay', async () => {
const mockCallback = jest.fn();
setTimeout(1000, mockCallback);
expect(mockCallback).not.toHaveBeenCalled();
await sleep(1000);
expect(mockCallback).toHaveBeenCalled();
});
When I run the test fails with the following error:
Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.
Obviously this is nowhere near that threshold. Any idea what I'm doing wrong?
[UPDATE]
I realized previously I had called jest.useFakeTimers()
before the test. After removing this and running the test again I still get a failure but it's not a timeout. Instead just simply
Expected mock function to have been called, but it was not called.
Note this is also the case when significantly increasing the sleep to 4000ms.
If instead I switch from setTimeout to
sleep(ONE_SECOND)
.then(mockCallback);
the test passes. Jest clearly modifies how setTimeout interacts in parallel with Promises, but it's not obvious as to what is going on.
Upvotes: 4
Views: 1295
Reputation: 45810
You just need to pass mockCallback
as the first argument to setTimeout
:
const sleep = ms => new Promise(res => setTimeout(res, ms));
it('should call callback after specified delay', async () => {
const mockCallback = jest.fn();
setTimeout(mockCallback, 1000); // <= pass mockCallback as first argument
expect(mockCallback).not.toHaveBeenCalled(); // Success!
await sleep(1000);
expect(mockCallback).toHaveBeenCalled(); // Success!
});
Upvotes: 3