我正在使用moment.js在我的React组件的辅助文件中执行大部分日期逻辑,但是我还没弄清楚如何在Jest a sinon.useFakeTimers()中模拟日期.
Jest文档只讨论定时器函数,如setTimeout,setInveral等,但没有帮助设置日期,然后检查我的日期函数是否执行他们想要做的事情.
这是我的一些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;
Run Code Online (Sandbox Code Playgroud)
这是我用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);
});
});
});
Run Code Online (Sandbox Code Playgroud)
现在这些测试通过,因为我正在使用时刻,我的函数使用时刻,但似乎有点不稳定,我想将日期设置为测试的固定时间.
有关如何实现这一点的任何想法?
Sim*_*enB 120
从 Jest 26 开始,这可以使用“现代”假定时器来实现,而无需安装任何 3rd 方模块:https : //jestjs.io/blog/2020/05/05/jest-26#new-fake-timers
jest
.useFakeTimers('modern')
.setSystemTime(new Date('2020-01-01').getTime());
Run Code Online (Sandbox Code Playgroud)
如果您希望所有测试的假计时器都处于活动状态,您可以timers: 'modern'在您的配置中进行设置:https : //jestjs.io/docs/en/configuration#timers-string
ste*_*nis 114
由于momentjs在Date内部使用,您只需覆盖该Date.now函数即可始终返回相同的时刻.
Date.now = jest.fn(() => 1487076708000) //14.02.2017
Run Code Online (Sandbox Code Playgroud)
Tim*_*ord 73
jest.spyOn适用于锁定时间:
let dateNowSpy;
beforeAll(() => {
// Lock Time
dateNowSpy = jest.spyOn(Date, 'now').mockImplementation(() => 1487076708000);
});
afterAll(() => {
// Unlock Time
dateNowSpy.mockRestore();
});
Run Code Online (Sandbox Code Playgroud)
小智 52
MockDate可以在jest测试中用于更改new Date()返回的内容:
var MockDate = require('mockdate');
// I use a timestamp to make sure the date stays fixed to the ms
MockDate.set(1434319925275);
// test code here
// reset to native Date()
MockDate.reset();
Run Code Online (Sandbox Code Playgroud)
Rob*_*yes 24
对于那些想要在new Date对象上模拟方法的人,您可以执行以下操作:
beforeEach(() => {
jest.spyOn(Date.prototype, 'getDay').mockReturnValue(2);
jest.spyOn(Date.prototype, 'toISOString').mockReturnValue('2000-01-01T00:00:00.000Z');
});
afterEach(() => {
jest.restoreAll()
});
Run Code Online (Sandbox Code Playgroud)
Duc*_*Mai 10
这对我有用:
const mockDate = new Date('14 Oct 1995')
global.Date = jest.fn().mockImplementation(() => mockDate) // mock Date "new" constructor
global.Date.now = jest.fn().mockReturnValue(mockDate.valueOf()) // mock Date.now
Run Code Online (Sandbox Code Playgroud)
所有仅基于模拟的答案Date.now()不会在任何地方都有效,因为某些包(例如moment.js)使用了new Date()替代方法。
MockDate在这种情况下,我认为唯一真正正确的答案是基于的。如果你不想使用外部包,你可以直接在你的beforeAll:
const DATE_TO_USE = new Date('2017-02-02T12:54:59.218Z');
// eslint-disable-next-line no-underscore-dangle
const _Date = Date;
const MockDate = (...args) => {
switch (args.length) {
case 0:
return DATE_TO_USE;
default:
return new _Date(...args);
}
};
MockDate.UTC = _Date.UTC;
MockDate.now = () => DATE_TO_USE.getTime();
MockDate.parse = _Date.parse;
MockDate.toString = _Date.toString;
MockDate.prototype = _Date.prototype;
global.Date = MockDate;
Run Code Online (Sandbox Code Playgroud)
从Jest版本开始29,您还可以执行以下操作:
jest.useFakeTimers({
now: 1673445238335,
});
Run Code Online (Sandbox Code Playgroud)
允许使用以下选项:
type FakeTimersConfig = {
/**
* If set to `true` all timers will be advanced automatically by 20 milliseconds
* every 20 milliseconds. A custom time delta may be provided by passing a number.
* The default is `false`.
*/
advanceTimers?: boolean | number;
/**
* List of names of APIs that should not be faked. The default is `[]`, meaning
* all APIs are faked.
*/
doNotFake?: Array<FakeableAPI>;
/**
* Use the old fake timers implementation instead of one backed by `@sinonjs/fake-timers`.
* The default is `false`.
*/
legacyFakeTimers?: boolean;
/** Sets current system time to be used by fake timers. The default is `Date.now()`. */
now?: number | Date;
/**
* The maximum number of recursive timers that will be run when calling `jest.runAllTimers()`.
* The default is `100_000` timers.
*/
timerLimit?: number;
};
Run Code Online (Sandbox Code Playgroud)
您可以在文档中阅读更多内容。
jest-date-mock是我编写的完整的javascript模块,用于测试jest上的Date。
import { advanceBy, advanceTo } from 'jest-date-mock';
test('usage', () => {
advanceTo(new Date(2018, 5, 27, 0, 0, 0)); // reset to date time.
const now = Date.now();
advanceBy(3000); // advance time 3 seconds
expect(+new Date() - now).toBe(3000);
advanceBy(-1000); // advance time -1 second
expect(+new Date() - now).toBe(2000);
clear();
Date.now(); // will got current timestamp
});
Run Code Online (Sandbox Code Playgroud)
仅将3个API用于测试用例。
小智 5
这就是我如何模拟Date.now()将测试年份设置为 2010 年的方法
jest
.spyOn(global.Date, 'now')
.mockImplementationOnce(() => new Date(`2010`).valueOf());
Run Code Online (Sandbox Code Playgroud)
以下是针对不同用例的几种可读方式。我更喜欢使用间谍而不是保存对原始对象的引用,原始对象可能会被其他一些代码意外覆盖。
jest
.spyOn(global.Date, 'now')
.mockImplementationOnce(() => Date.parse('2020-02-14'));
Run Code Online (Sandbox Code Playgroud)
let dateSpy;
beforeAll(() => {
dateSpy = jest
.spyOn(global.Date, 'now')
.mockImplementation(() => Date.parse('2020-02-14'));
});
afterAll(() => {
dateSpy.mockRestore();
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
46713 次 |
| 最近记录: |