Fixing timeout errors when mocking Date in Jest using Supertest
I’ve recently been running into timeout errors when trying to mock timer functions when using Jest and Supertest to test my API routes. Jest 26 brough a new timer faking interface which supports the ability to mock Date. We can use setSystemTime rather than having to create a Spy, which in most cases makes the process as simple as:
const mockDate = new Date(2023, 10, 31);
describe("Example", () => {
beforeEach(() => {
jest.useFakeTimers("modern");
jest.setSystemTime(mockedDate);
});
afterEach(() => {
jest.useRealTimers();
});
test("Example test", () => {
// Write assertions here
});
});
However, my tests kept failing as I ran into timeout issues when using Supertest and trying to test my API routes … I traced this issue back to the fact that Jest is mocking everything under the moon (documentation), shown here below in the default config options:
type FakeableAPI =
| 'Date'
| 'hrtime'
| 'nextTick'
| 'performance'
| 'queueMicrotask'
| 'requestAnimationFrame'
| 'cancelAnimationFrame'
| 'requestIdleCallback'
| 'cancelIdleCallback'
| 'setImmediate'
| 'clearImmediate'
| 'setInterval'
| 'clearInterval'
| 'setTimeout'
| 'clearTimeout';
Yet, some of these are needed for Supertest to not timeout, namely: setImmediate and nextTick. This makes for a quick fix:
const mockDate = new Date(2023, 10, 31);
describe("Example", () => {
beforeEach(() => {
jest.useFakeTimers({ doNotFake: ["nextTick", "setImmediate"] });
jest.setSystemTime(mockedDate);
});
afterEach(() => {
jest.useRealTimers();
});
test("Example test", () => {
// Write assertions here
});
});
Voila! Quick and easy fix 🎉