Reputation: 1694
I have this codepiece in my React component, which renders an HTML in the end:
new Date(createDate).toLocaleDateString()
My local machine and our build machine have different locales set, so the result of this function is not coherent. So as you'd expect, the unit test passes on my machine and fails on build machine, or vice versa.
I want to mock "toLocalDateString" so that it always uses the same locale, say 'en-US', or at least it always returns the same string. Our test framework is jest. How do I achieve this goal?
I tried this in my test.spec.js but it didn't have any effect at all:
Date.prototype.toLocaleDateString = jest.fn().mockReturnValue('2020-04-15')
expect(component).toMatchSnapshot()
I still get the same old toLocalDateString implementation in the snapshot, my mockReturnValue is not taken into account.
Upvotes: 13
Views: 11319
Reputation: 759
I couldn't get Jamund Ferguson's answer to work with Vitest because their .spyOn
mechanism seems to be slightly different. However, by adding a new file to my setupFiles with the following code, I was able to get this working properly:
const origDate = Date.prototype.toLocaleDateString
beforeAll(() => {
// eslint-disable-next-line no-extend-native
Object.defineProperty(Date.prototype, 'toLocaleDateString', {
value() {
return origDate.call(this, 'en-AU')
},
})
})
afterAll(() => {
// eslint-disable-next-line no-extend-native
Object.defineProperty(Date.prototype, 'toLocaleDateString', {
value() {
return origDate.call(this)
},
})
})
Upvotes: 0
Reputation: 17014
If you want to respond to the current date, but choose an alternative (fixed) locale I found this works pretty well. You can place it in the test file or in the setupTests.js/ts
file to apply it:
const origDate = global.Date.prototype.toLocaleDateString;
jest.spyOn(global.Date.prototype, 'toLocaleDateString').mockImplementation(function () {
return origDate.call(this, 'en-US');
});
This example will fix all localeDateString output to en-US
. Note you have to use function(){}
and not ()=>{}
because you're relying on this
to be set correctly by the caller.
Upvotes: 4
Reputation: 1014
I may be a bit late but hope it helps someone
let mockDate;
beforeAll(() => {
mockDate = jest.spyOn(Date.prototype, 'toLocaleTimeString').mockReturnValue('2020-04-15');
});
afterAll(() => {
mockDate.mockRestore();
});
Upvotes: 8
Reputation: 29
Would the below code work well for you? I am mocking the date object this way.
const realDateToLocaleDateString = Date.prototype.toLocaleDateString.bind(global.Date);
const toLocaleDateStringStub = jest.fn(() => '2020-04-15');
global.Date.prototype.toLocaleDateString = toLocaleDateStringStub;
const date = new Date();
console.log(date.toLocaleDateString()); // returns 2020-04-15
global.Date.prototype.toLocaleDateString = realDateToLocaleDateString;
Upvotes: -1
Reputation: 11283
Can you wrap
new Date(createDate).toLocaleDateString()
in a function, pass it as prop to component and then mock it?
Upvotes: 2