TIL: Since v26 of Jest (which has been out for some time now), we've been able to fake/mock times natively in tests with jest.useFakeTimers
function, including mocking the Date
object. In my case, I needed to set a specific date and time for some components and then modify the time on a per-test basis to verify proper behvaiour.
Overview
To set current time in Jest to a specific time, call
// example
// setSystemTime accepts any Date object or Unix timestamp
jest.useFakeTimers().setSystemTime(new Date('2022-02-20'));
The result is that calling Date.now()
in our tests will return the that we set the system time to:
new Date().getTime(); // 2022-02-20 00:00:00
Setting fake times globally or by test
Calling useFakeTimers
function at the file level with set it globally for all tests. A fake time can be set for a specific test-suite like so:
beforeEach(() => {
jest.useFakeTimers().setSystemTime(new Date('2022-02-20'));
});
// clean up
afterEach(() => {
// run any pending timers in your tests, e.g. setTimeout calls
jest.runOnlyPendingTimers();
// ready to switch back to real timers, inc. Date
jest.useRealTimers();
});
Using fake time in tests
Once the fake time has been set, any calls to Date.now()
will return the fake time. If we need to customise the return value of Date.now()
in one of our tests to have it return some new time relative to our fake time, we can do so the following way:
// set Date.now() calls withing the implementation
// to return a new time 1s ahead of our fake time
jest.spyOn(Date, 'now').mockImplementation(() => +Date.now() + 1000);
And that's it!
Resources
- Jest docs on timer mocks
- For testing library users — Using Fake Timers by Kent C Dodds