我使用moment.js在React组件的辅助文件中执行大部分日期逻辑,但我还没有弄清楚如何在Jest a lasinon.useFakeTimers()
中模拟日期。
Jest文档只介绍计时器函数,如setTimeout
,setInterval
等,但不帮助设置日期,然后检查my date函数是否完成了它们的任务。
以下是我的一些JS文件:
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;
下面是我用玩笑设置的:
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);
});
});
});
现在这些测试通过了,因为我使用的是矩,我的函数使用的是矩,但它似乎有点不稳定,我想为测试设置一个固定的时间。
你知道怎样才能做到吗?
因为Momjs在内部使用Date
,所以您可以覆盖Date.now
函数以始终返回相同的时刻。
Date.now = jest.fn(() => 1487076708000) //14.02.2017
或
Date.now = jest.fn(() => new Date(Date.UTC(2017, 1, 14)).valueOf())
从Jest 26开始,这可以通过使用“现代”假定时器实现,而无需安装任何第三方模块:https://jestjs.io/blog/2020/05/05/jest-26#new-假计时器
jest
.useFakeTimers()
.setSystemTime(new Date('2020-01-01').getTime());
如果你想让假定时器在所有测试中都是活动的,你可以在你的配置中设置定时器:'现代'
:https://jestjs.io/docs/configuration#timers-string
编辑:从Jest 27开始,现代伪计时器是默认值,因此您可以将参数放到useFakeTimers
中。
jest.spy锁定时间:
let dateNowSpy;
beforeAll(() => {
// Lock Time
dateNowSpy = jest.spyOn(Date, 'now').mockImplementation(() => 1487076708000);
});
afterAll(() => {
// Unlock Time
dateNowSpy.mockRestore();
});