I'm using moment.js to do most of my date logic in a helper file for my React components but I haven't been able to figure out how to mock a date in Jest a la sinon.useFakeTimers()
.
The Jest docs only speak about timer functions like setTimeout
, setInterval
etc but don't help with setting a date and then checking that my date functions do what they're meant to do.
Here is some of my JS file:
var moment = require('moment');
var DateHelper = {
DATE_FORMAT: 'MMMM D',
API_DATE_FORMAT: 'YYYY-MM-DD',
formatDate: function(date) {
return date.format(this.DATE_FORMAT);
},
isDateToday: function(date) {
return this.formatDate(date) === this.formatDate(moment());
}
};
module.exports = DateHelper;
and here is what I've set up using Jest:
jest.dontMock('../../../dashboard/calendar/date-helper')
.dontMock('moment');
describe('DateHelper', function() {
var DateHelper = require('../../../dashboard/calendar/date-helper'),
moment = require('moment'),
DATE_FORMAT = 'MMMM D';
describe('formatDate', function() {
it('should return the date formatted as DATE_FORMAT', function() {
var unformattedDate = moment('2014-05-12T00:00:00.000Z'),
formattedDate = DateHelper.formatDate(unformattedDate);
expect(formattedDate).toEqual('May 12');
});
});
describe('isDateToday', function() {
it('should return true if the passed in date is today', function() {
var today = moment();
expect(DateHelper.isDateToday(today)).toEqual(true);
});
});
});
Now these tests pass because I'm using moment and my functions use moment but it seems a bit unstable and I would like to set the date to a fixed time for the tests.
Any idea on how that could be accomplished?
As of Jest 26 this can be achieved using "modern" fake timers without needing to install any 3rd party modules: https://jestjs.io/blog/2020/05/05/jest-26#new-fake-timers
jest
.useFakeTimers()
.setSystemTime(new Date('2020-01-01'));
If you want the fake timers to be active for all tests, you can set timers: 'modern'
in your configuration: https://jestjs.io/docs/configuration#timers-string
EDIT: As of Jest 27 modern fake timers is the default, so you can drop the argument to useFakeTimers
.