The Date
is a global object in Javascript. This means that it is a property of window
(in the browser), of global
(in Node.js) or globalThis
(in browsers modern and recent versions of Node.js).
Since Jest runs on Node.js, we can use global
to access it. From Node.js 12.4.0 you can use globalThis
also.
Thus, to mock Date
, we must "spy" the object containing it. Thus:
const mockedDate = new Date(2000, 9, 1, 7);
jest.spyOn(global, 'Date').mockImplementation(() => {
return mockedDate;
});
How you are using Typescript, in the specific case of mock of Date
, will pass any
as "argument" for the two generics of spyOn
, since Jest’s type definitions have a certain conflict regarding the type of Date
. That’s because Date
can be applied (returning type string
) or instantiated, returning type Date
. Since both cases are possible, Typescript is not able to define which of the overloads will be used.
Therefore, as the definition of types would only take the first case into account (in the case, string
), we have to do:
const mockedDate = new Date(2000, 9, 1, 7);
// ↓↓↓↓↓↓↓↓↓↓
jest.spyOn<any, any>(global, 'Date').mockImplementation(() => {
return mockedDate;
})
Now whenever you build a new date, you will have it mocked. Note that we had to instantiate the date to be returned by mock outside the callback of mockImplementation
not to fall into a loop infinite.
If we give a console.log(new Date())
now we will have the following exit:
console.log
2000-10-01T10:00:00.000Z
@Luizfelipe the
Date.now()
is working yes, but what I need is to "mock" thenew Date()
. It is without using theDate.now()
. Got it?– Deividson Damasio