How to mock a constructor like new Date()
Update: this answer is the approach for jest < version 26
see this answer for recent jest versions.
You can mock a constructor like new Date() using jest.spyOn
as below:
test('mocks a constructor like new Date()', () => {
console.log('Normal: ', new Date().getTime())
const mockDate = new Date(1466424490000)
const spy = jest
.spyOn(global, 'Date')
.mockImplementation(() => mockDate)
console.log('Mocked: ', new Date().getTime())
spy.mockRestore()
console.log('Restored: ', new Date().getTime())
})
And the output looks like:
Normal: 1566424897579
Mocked: 1466424490000
Restored: 1566424897608
See the reference project on GitHub.
Note: If you are using TypeScript and you would encounter a compilation error, Argument of type '() => Date' is not assignable to parameter of type '() => string'. Type 'Date' is not assignable to type 'string'
. In this case, a workaround is to use the mockdate library, which can be used to change when "now" is. See this question for more details.
You can use jasmine's spyOn (jest is built on jasmine) to mock Date's prototype for getDate as follows:
spyOn(Date.prototype, 'setDate').and.returnValue(DATE_TO_TEST_WITH);
SpyOn will also clean up after it's self and only lasts for the scope of the test.
Since jest 26, you can use the 'modern' fakeTimers implementation (see article here) wich supports the method jest.setSystemTime
.
beforeAll(() => {
jest.useFakeTimers('modern');
jest.setSystemTime(new Date(2020, 3, 1));
});
afterAll(() => {
jest.useRealTimers();
});
Note that 'modern'
will be the default implementation from jest version 27.
See documentation for setSystemTime
here.