내 React 구성 요소에 대한 도우미 파일에서 대부분의 날짜 논리를 수행하기 위해 moment.js를 사용하고 있지만 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);
});
});
});
이제 모멘트를 사용하고 내 함수가 모멘트를 사용하기 때문에 이러한 테스트는 통과했지만 약간 불안정 해 보이며 테스트를 위해 날짜를 고정 시간으로 설정하고 싶습니다.
그것이 어떻게 성취 될 수 있는지에 대한 아이디어가 있습니까?
답변
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();
답변
momentjs는 Date
내부적으로 사용하기 때문에 Date.now
항상 같은 순간을 반환하도록 함수를 덮어 쓸 수 있습니다 .
Date.now = jest.fn(() => 1487076708000) //14.02.2017
또는
Date.now = jest.fn(() => new Date(Date.UTC(2017, 1, 14)).valueOf())
답변
jest.spyOn 은 잠금 시간에 대해 작동합니다.
let dateNowSpy;
beforeAll(() => {
// Lock Time
dateNowSpy = jest.spyOn(Date, 'now').mockImplementation(() => 1487076708000);
});
afterAll(() => {
// Unlock Time
dateNowSpy.mockRestore();
});
답변
jest-date-mock 은 내가 작성한 완전한 자바 스크립트 모듈이며, 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
});
테스트 케이스에는 3 개의 API 만 사용하십시오.
- advanceBy (ms) : ms 단위로 날짜 타임 스탬프를 진행합니다.
- advanceTo ([timestamp]) : 날짜를 타임 스탬프로 재설정하고 기본값은 0입니다.
- clear () : 모의 시스템을 종료합니다.
답변
새 Date 객체에 대한 모의 메서드를 원하는 사람들을 위해 다음을 수행 할 수 있습니다.
beforeEach(() => {
jest.spyOn(Date.prototype, 'getDay').mockReturnValue(2);
jest.spyOn(Date.prototype, 'toISOString').mockReturnValue('2000-01-01T00:00:00.000Z');
});
afterEach(() => {
jest.restoreAll()
});
답변
의 모의만을 기반으로 한 모든 대답 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;
답변
몇 가지 대안을 제시하고 싶습니다.
스텁이 필요한 경우 format()
(로케일 및 시간대에 따라 달라질 수 있습니다!)
import moment from "moment";
...
jest.mock("moment");
...
const format = jest.fn(() => 'April 11, 2019')
moment.mockReturnValue({ format })
스텁 만 필요한 경우 moment()
:
import moment from "moment";
...
jest.mock("moment");
...
const now = "moment(\"2019-04-11T09:44:57.299\")";
moment.mockReturnValue(now);
에 대한 테스트와 관련하여 isDateToday
위의 기능을, 나는 간단한 방법은 모의하지 않는 것 생각 moment
전혀