I'm trying to mock new Date()
to return a specific date. The following code:
const now = new Date()
jest.spyOn(global, 'Date').mockImplementation(() => now)
gives a compilation error: Argument of type '() => Date' is not assignable to parameter of type '() => string'. Type 'Date' is not assignable to type 'string'
.
I think the reason is that jest thinks I'm trying to mock Date()
instead of new Date()
. Indeed, Date()
returns a string. How can I solve this issue?
To mock a constructor like new Date() with Jest and JavaScript, we can use the setSystemTime method. beforeAll(() => { jest. useFakeTimers("modern"); jest. setSystemTime(new Date(2022, 3, 1)); }); afterAll(() => { jest.
Mock the whole Date class with a fixed date instance Date = class extends Date { constructor(date) { if (date) { return super(date); } return currentDate; } }; expect(getCurrentDate()). toEqual(new Date('2019-05-14T11:01:58.135Z')); // Cleanup global. Date = realDate; });
In order to mock a constructor function, the module factory must return a constructor function. In other words, the module factory must be a function that returns a function - a higher-order function (HOF). Since calls to jest. mock() are hoisted to the top of the file, Jest prevents access to out-of-scope variables.
it("should return decremented duration as time passes", () => { const timer = new Timer(5, true); jasmine. clock(). mockDate(new Date(startingTime + 1000)); expect(timer.
well I tried this solution, and it worked..
class MockDate extends Date {
constructor() {
super("2020-05-14T11:01:58.135Z"); // add whatever date you'll expect to get
}
}
and in the beforeEach of that test, I added:
// @ts-ignore
global.Date = MockDate;
this way whenever I called a function that had new Date() inside, it would return the date I added in the constructor of the MockDate class above!
A workaround is to use the mockdate library, which can be used to change when "now" is.
const MockDate = require('mockdate');
test('Mock Date to change when "now" is', () => {
console.log('Normal: ', new Date().getTime());
MockDate.set(new Date(1466424490000));
console.log('Mocked: ', new Date().getTime());
MockDate.reset();
console.log('Restored: ', new Date().getTime());
});
And the test result is like:
$ npm run test
> jest
PASS src/test.ts
✓ Mock Date to change when "now" is (8ms)
console.log src/test.ts:4
Normal: 1585505136315
console.log src/test.ts:8
Mocked: 1466424490000
console.log src/test.ts:12
Restored: 1585505136322
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 1.804s
See the reference project on GitHub.
Daryn's inference comment on Arron's answer works great with no extra packages.
const mockDate = new Date();
jest.spyOn(global, "Date").mockImplementation(() => (mockDate as unknown) as string);
const myDate = new Date();
Just tell the compiler what it wants to hear: say its a string with cast to unknown followed by the cast to string:
const now = new Date() as unknown as string
I have the same issue when mocking a new Date()
using jest typescript
when try to mocking Date inside a function :
export const checkValidTime(): boolean => {
const now = new Date();
const maxAllowTime = new Date('2020-02-02 09:00:00');
console.log(`currentTime: ${now.toLocaleString()}`);
console.log(`maxAllowTime: ${maxAllowTime.toLocaleString()}`);
return now > maxAllowTime;
}
Mocking solution in unit test:
const mockDate = new Date('2021-09-03 08:00:10');
jest
.spyOn(global, 'Date')
.mockImplementationOnce(() => (mockDate as unknown) as string);
const valid = checkDateTime();
expect(valid).toEqual(true);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With