Jest에서 모의 데이트를 어떻게 설정하나요?
React 구성 요소에 대한 도우미 파일에서 대부분의 날짜 논리를 수행하기 위해 moment.js를 사용하고 있지만 Jest a la 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;
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
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.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;
I would like to offer some alternative approaches.
If you need to stub format()
(which can be locale and timezone dependent!)
import moment from "moment";
...
jest.mock("moment");
...
const format = jest.fn(() => 'April 11, 2019')
moment.mockReturnValue({ format })
If you only need to stub moment()
:
import moment from "moment";
...
jest.mock("moment");
...
const now = "moment(\"2019-04-11T09:44:57.299\")";
moment.mockReturnValue(now);
Regarding the test for the isDateToday
function above, I believe the simplest way would be not to mock moment
at all
I'd like use Manual Mocks, so it can use in all tests.
// <rootDir>/__mocks__/moment.js
const moment = jest.requireActual('moment')
Date.now = jest.fn(() => 1558281600000) // 2019-05-20 00:00:00.000+08:00
module.exports = moment
Goal is to mock new Date() with a fixed date wherever it's used during the component rendering for test purposes. Using libraries will be a overhead if the only thing you want is to mock new Date() fn.
Idea is to store the global date to a temp variable, mock the global dae and then after usage reassign temp to global date.
export const stubbifyDate = (mockedDate: Date) => {
/**
* Set Date to a new Variable
*/
const MockedRealDate = global.Date;
/**
* Mock Real date with the date passed from the test
*/
(global.Date as any) = class extends MockedRealDate {
constructor() {
super()
return new MockedRealDate(mockedDate)
}
}
/**
* Reset global.Date to original Date (MockedRealDate) after every test
*/
afterEach(() => {
global.Date = MockedRealDate
})
}
Usage in your test would be like
import { stubbyifyDate } from './AboveMethodImplementedFile'
describe('<YourComponent />', () => {
it('renders and matches snapshot', () => {
const date = new Date('2019-02-18')
stubbifyDate(date)
const component = renderer.create(
<YourComponent data={}/>
);
const tree = component.toJSON();
expect(tree).toMatchSnapshot();
});
});
참고URL : https://stackoverflow.com/questions/29719631/how-do-i-set-a-mock-date-in-jest
'developer tip' 카테고리의 다른 글
SQL Server에서 동일한 예외를 다시 발생시키는 방법 (0) | 2020.10.11 |
---|---|
런타임에 Android에서 텍스트의 일부를 굵게 만드는 방법은 무엇입니까? (0) | 2020.10.11 |
스핑크스 빌드 실패-autodoc이 모듈을 가져 오거나 찾을 수 없습니다. (0) | 2020.10.10 |
Cassandra cql 테이블에서 모든 행 삭제 (0) | 2020.10.10 |
"Class"변수를 instanceof로 전달할 수없는 이유는 무엇입니까? (0) | 2020.10.10 |