我使用moment.js在我的React组件的帮助文件中做大部分的日期逻辑,但我还没有弄清楚如何在Jest a la sinon.useFakeTimers()中模拟日期。
Jest文档只谈到了计时器函数,如setTimeout, setInterval等,但没有帮助设置日期,然后检查我的日期函数是否做了他们应该做的事情。
这是我的一些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设置的:
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);
});
});
});
现在这些测试通过了,因为我使用了moment,我的函数也使用了moment,但它似乎有点不稳定,我想将日期设置为测试的固定时间。
你知道该怎么做吗?
下面的测试存根Date在测试生命周期中返回一个常量。
如果你在你的项目中使用了new Date(),那么你可以在你的测试文件中模拟它,如下所示:
beforeEach(async () => {
let time_now = Date.now();
const _GLOBAL: any = global;
_GLOBAL.Date = class {
public static now() {
return time_now;
}
};
}
现在,无论您在测试文件中使用new Date(),它都会产生相同的时间戳。
注意:你可以用beforeAll替换beforeEach。而_GLOBAL只是一个满足typescript的代理变量。
完整的代码我尝试:
let time_now;
const realDate = Date;
describe("Stubbed Date", () => {
beforeAll(() => {
timeNow = Date.now();
const _GLOBAL: any = global;
_GLOBAL.Date = class {
public static now() {
return time_now;
}
constructor() {
return time_now;
}
public valueOf() {
return time_now;
}
};
});
afterAll(() => {
global.Date = realDate;
});
it("should give same timestamp", () => {
const date1 = Date.now();
const date2 = new Date();
expect(date1).toEqual(date2);
expect(date2).toEqual(time_now);
});
});
这对我很管用。
下面的测试存根Date在测试生命周期中返回一个常量。
如果你在你的项目中使用了new Date(),那么你可以在你的测试文件中模拟它,如下所示:
beforeEach(async () => {
let time_now = Date.now();
const _GLOBAL: any = global;
_GLOBAL.Date = class {
public static now() {
return time_now;
}
};
}
现在,无论您在测试文件中使用new Date(),它都会产生相同的时间戳。
注意:你可以用beforeAll替换beforeEach。而_GLOBAL只是一个满足typescript的代理变量。
完整的代码我尝试:
let time_now;
const realDate = Date;
describe("Stubbed Date", () => {
beforeAll(() => {
timeNow = Date.now();
const _GLOBAL: any = global;
_GLOBAL.Date = class {
public static now() {
return time_now;
}
constructor() {
return time_now;
}
public valueOf() {
return time_now;
}
};
});
afterAll(() => {
global.Date = realDate;
});
it("should give same timestamp", () => {
const date1 = Date.now();
const date2 = new Date();
expect(date1).toEqual(date2);
expect(date2).toEqual(time_now);
});
});
这对我很管用。