@SimenB 25-05-2020 ํธ์ง: ์ ๋ฐ์ดํธ๋ ๋ต๋ณ ๋ณด๊ธฐ: https://github.com/facebook/jest/issues/2234#issuecomment -633402727
ํ์ฌ ๋ ์ง๋ฅผ ์กฐ๋กฑํ๋ ๋ฐฉ๋ฒ์ด ์์ต๋๊น? new Date()
๋๋ Date.now()
๊ฐ ํ์ฌ ์๊ฐ ๋์ ๋ชจ์ ์๊ฐ์ ๋ฐํํ๋๋ก ํ์๊ฒ ์ต๋๊น?
Date.now = jest.fn
๋๋ global.Date = jest.fn()
.
์ด๊ฒ์ผ๋ก ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ ๋ค๋ฅธ ์ฌ๋์ ๊ฒฝ์ฐ ์ ์ญ Date ๊ฐ์ฒด์ ์์ฑ์ ์ด์ธ์ ์์ฑ์ด ์๊ธฐ ๋๋ฌธ์ ๋ช ๊ฐ์ง ๋ฌธ์ ๊ฐ ์์์ต๋๋ค. ๋๋ ๋ค์์ ์ํํ๋ค.
const DATE_TO_USE = new Date('2016');
const _Date = Date;
global.Date = jest.fn(() => DATE_TO_USE);
global.Date.UTC = _Date.UTC;
global.Date.parse = _Date.parse;
global.Date.now = _Date.now;
์์ฑ์๊ฐ ํธ์ถ๋๋ ๋ฐฉ์์ ๋ํด ์ฃผ์ฅํ ํ์๊ฐ ์๋ค๋ฉด ํ์ฅ์ผ๋ก ์ถฉ๋ถํ ์ ์์ต๋๋ค.
const constantDate = new Date('2017-06-13T04:41:20')
/*eslint no-global-assign:off*/
Date = class extends Date {
constructor() {
return constantDate
}
}
์ด๊ฒ์ Date.now()
๋ํด ๊ฝค ์ ์๋ํฉ๋๋ค.
const now = Date.now()
Date.now = jest.genMockFunction().mockReturnValue(now)
๋ชจ์ ๋ฐ์ดํธ๋ฅผ ํ ๋๋ง๋ค ์ค์ ๋ฒ์ ์ผ๋ก ๋๋๋ฆฌ๋ ๊ฒ์ ์์ง ๋ง์ญ์์ค.
@callemo ์ฃผ์ ๋ค์์ ๋ค์ ์ค๋ํซ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
describe('getTimestamp', () => {
const RealDate = Date
function mockDate (isoDate) {
global.Date = class extends RealDate {
constructor () {
return new RealDate(isoDate)
}
}
}
afterEach(() => {
global.Date = RealDate
})
it('should return timestamp', () => {
mockDate('2017-11-25T12:34:56z')
expect(getTimestamp()).toEqual('20171125123456')
})
})
ํ๋ฆผ์์ด Date๋ jest.runTimersToTime()
๋ฐ ๋ค๋ฅธ ์๊ฐ ๋ชจ์ ๊ธฐ๋ฅ์ ์คํํ ๋๋ ์์ผ๋ก ์ด๋ํด์ผ ํฉ๋๋ค. ๋ด ์ฝ๋์ ์ผ๋ถ๋ ์๊ฐ์ ์์กดํ๊ณ ์ผ๋ถ๋ ์๊ฐ ์ด๊ณผ์ ์์กดํ๊ธฐ ๋๋ฌธ์ ๋์ผํ ๋ฌธ์ ์ ๋ฌผ๋ ธ์ต๋๋ค. ๋์์ ์กฐ๋กฑํ๋ ๊ฒ -- ์ฆ ์กฐ๋กฑ๋ ํ์ด๋จธ๋ฅผ ์คํํ๊ณ Date.now
๋ฐ Performance.now
์กฐ๋กฑ์ ์ ํํ๋ ๊ฒ์ ์ต๊ณ ์ ๊ฒฝํ์ด ์๋๋๋ค.
"ํตํฉ" ํ์ด๋จธ ๋ชจ์์ ๋ํ ์๋ฃจ์
์ ๋ค์๊ณผ ๊ฐ์ด jest
๋ด์ฅ ํจ์ ๋์ lolex
์ฌ์ฉํ๋ ๊ฒ์
๋๋ค.
import lolex from 'lolex'
describe('tests', () => {
let clock
beforeEach(() => {clock = lolex.install()})
afterEach(() => {clock = clock.uninstall()})
test('garbage collects after keep alive', () => {
// ...
clock.tick(500)
// ...
})
})
ํ์ง๋ง ์ด ๊ธฐ๋ฅ์ด ๋ด์ฅ๋์ด ์์ผ๋ฉด ์ข์ ๊ฒ์ ๋๋ค.
์ค๋๋ ๋ฌธ์ ์ง๋ง mockdate
์ฌ์ฉํ๋ฉด ์ฝ๊ฒ ๋ง๋ค ์ ์์ต๋๋ค. https://www.npmjs.com/package/mockdate
https://jasmine.github.io/2.2/introduction?spec=jasmine.any#section -Mocking_the_Date
describe("Mocking the Date object", function(){
it("mocks the Date object and sets it to a given time", function() {
var baseTime = new Date(2013, 9, 23);
jasmine.clock().mockDate(baseTime);
jasmine.clock().tick(50);
expect(new Date().getTime()).toEqual(baseTime.getTime() + 50);
});
});
@drpicox ๊ทธ๊ฒ์ ์ข์ ์๋ฃจ์
์ด์ง๋ง AFAIK๋ performance.now()
์กฐ๋กฑํ์ง ์์ต๋๋ค.
์ฌ์ค Jest์์๋ ์๋ํ์ง ์์ต๋๋ค. Jest๋ Jasmine v1.5.2-lite๋ฅผ ์ฌ์ฉํ๋ฏ๋ก ์๊ณ๊ฐ ์์ต๋๋ค. lolex
์์ต๋๋ค.
Date.now()
๋ ๋๋ถ๋ถ์ ์์ฉ ํ๋ก๊ทธ๋จ์ ์ถฉ๋ถํฉ๋๋ค. permofrmance.now()
์์ง ๋
ธ๋์ ์กด์ฌํ์ง ์์ต๋๋ค(์: SSR์์๋ ์ฌ์ฉํ ์ ์์). ๋ฐ๋ผ์ ํฐ ๋ฌธ์ ๋ ์๋ ๊ฒ ๊ฐ์ต๋๋ค.
๋ฌผ๋ก lolex๋ jest์ ํตํฉ๋์ง ์์ต๋๋ค.
@drpicox ์, ๊ทธ๋ฌ๋ฉด ์๋ํ์ง ์๋๋ค๋ ๊ฒ์ ์๋ ๊ฒ์ด ์ข์ต๋๋ค.
performance.now()
๋ v8.5.0 ์ดํ๋ก ๋
ธ๋์ ์กด์ฌํฉ๋๋ค. ๋ด์ฅ ๋ชจ๋ 'perf_hooks'
์์ performance
๋ฅผ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.
๊ทธ๋๋ ํ์ฌ ์ํฉ๊ณผ ์ด์ ๋ํ ํฌํ/๋๊ธ ์๋ฅผ ๊ฐ์ํ ๋ @cpojer ์ ping์
FWIW lolex๋ฅผ ํตํฉํ๊ณ ์ถ์ต๋๋ค. Jest์ ๋ฐฐํฐ๋ฆฌ๊ฐ ์๋ค๊ณ ์๊ฐ๋๋ ๊ณณ์์ ์ฌ์ฉํ๋ ์ ์ผํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค.
@cpojer ์ด๋ค ์์ผ๋ก๋ ์ด๊ฒ์ ๋ค์ ์ด ์ ์์ต๋๋ค. ํ์ฌ๋ก์๋, ์ ๋ง ๋ ์ง๋ฅผ ์กฐ๋กฑํ๊ณ ์ฌ์ด ๋ฐฉ๋ฒ์ผ๋ก ์๊ฐ์ ํจ์ค๋ฅผ ์๋ฎฌ๋ ์ด์ ํ ์์๋ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค.
jasmine์๋ ๋ค์์ ํตํด ๋ ์ง ์ ์ฌ์ ์๊ฐ์ ์กฐ๋กฑํ ์ ์๋ ์๊ณ ํด๋์ค๊ฐ ์์ต๋๋ค.
jasmine.clock().install(); //in a beforeEach
jasmine.clock().uninstall(); // in a AfterEach
jasmine.clock().mockDate(new Date('1984/12/15'));
// and very important... the pass of time!
jasmine.clock().tick(100);
๋น์ทํ ๊ธฐ๋ฅ์ ๊ธฐ๋ณธ์ ์ผ๋ก ๊ฐ๊ณ ์ถ์ต๋๋ค. https://github.com/jasmine/jasmine/blob/master/src/core/Clock.js
๊ทํ์ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ์ง์ํ๋ Lolex๋ก ๋ง์ด๊ทธ๋ ์ด์ ์ ์๋ํ ๊ฒ์ ๋๋ค. #5165 ์ฐธ์กฐ
ํ ์คํธ ํ๊ฒฝ์ _outside_ ๋ ์ง๋ฅผ ์กฐ๋กฑํด์ผ ํ๋ ๊ฒฝ์ฐ. ๋ ์ง๊ฐ ํ์๋๋ UI์ ์์ธก ๊ฐ๋ฅํ ์ด๋ฏธ์ง ์ค๋ ์ท์ ์ฐ์ด์ผ ํ์ต๋๋ค.
์ด๊ฒ์ ๋๋ฅผ ์ํด ์ผํ์ต๋๋ค.
https://github.com/schickling/timemachine
timemachine.config({
dateString: 'December 25, 1991 13:12:59'
});
console.log(new Date()); // December 25, 1991 13:12:59
@omegdadisc ์ ์ ์์ ๋ด๊ฐ ์๊ฐํ๋ ์ต๊ณ ์
๋๋ค. ํญ์ ๊ฐ์ ๋ ์ง๋ฅผ ๋ฐํํ๋ Mocking Date(์ฒซ ๋ฒ์งธ ๋ต๋ณ์์ ์ ์ํ ๋๋ก)๋ new Date(2018, 2, 3)
์ ๊ฐ์ ๊ฒ์ ์๋ง์ผ๋ก ๋ง๋ค๋ฏ๋ก ๋์๊ฒ ์ ํจํ ์ต์
์ด ์๋๋๋ค.
๋ํ Travis์์์ ๊ฐ์ด ๋ชจ๋ ๊ณณ์์ ์์ ํ ์๋ํ๊ณ ๋์ผํ ๊ฒฐ๊ณผ๋ฅผ ์์ฑํ๋ ค๋ฉด ์ ํํ ์๊ฐ๋๋ฅผ ์ง์ ํด์ผ ํฉ๋๋ค.
timemachine.config({
dateString: 'December 25, 1991 13:12:59 GMT'
});
๋ค์ ํ ์คํธ ์คํ Date๋ ํ ์คํธ ์๋ช ์ฃผ๊ธฐ ๋์ ์์๋ฅผ ๋ฐํํฉ๋๋ค.
let timeNow;
const realDate = Date;
describe("Stubbed Date", () => {
beforeAll(() => {
timeNow = Date.now();
const _GLOBAL: any = global;
_GLOBAL.Date = class {
public static now() {
return timeNow;
}
constructor() {
return timeNow;
}
public valueOf() {
return timeNow;
}
};
});
afterAll(() => {
global.Date = realDate;
});
it("provides constant timestamps", () => {
const ts1 = Date.now();
const ts2 = +new Date();
expect(ts1).toEqual(ts2);
expect(ts2).toEqual(timeNow);
});
});
_GLOBAL
๋ typescript๋ฅผ ๋ง์กฑ์ํค๊ธฐ ์ํ ํ๋ก์ ๋ณ์์ผ ๋ฟ์
๋๋ค.
๋๋ Date.now()
๋ฅผ ์กฐ๋กฑํด์ผ ํ๋ค
๊ตฌ์ฑ์์ ๋๋ ํ ์คํธ๊ฐ ์๋ํ๊ธฐ ์ ์ ์๋ ์ค์ ์ค์ ํ์ญ์์ค.
jest.spyOn(Date, 'now').mockImplementation(() => 1479427200000)
@vcarel ์ ์ ๊ทผ ๋ฐฉ์์ด ๋ง์์
describe('getTimestamp', () => {
const RealDate = Date
function mockDate (isoDate) {
global.Date = class extends RealDate {
constructor(...theArgs) {
if (theArgs.length) {
return new RealDate(...theArgs);
}
return new RealDate(isoDate);
}
static now() {
return new RealDate(isoDate).getTime();
}
}
}
afterEach(() => {
global.Date = RealDate
})
it('should return timestamp', () => {
mockDate('2017-11-25T12:34:56z')
expect(getTimestamp()).toEqual('20171125123456')
})
})
https://github.com/boblauer/MockDate์ ๋ง์กฑํ๋ ์ด๊ฒ์ ์ฌ์ฉํ๊ณ ์์ต๋๋ค.
๋๋ ์ด๊ฒ์ํ๋ค
~~~
์ค๋ช
('ํ
์คํธ', () => {
const constantDate = ์๋ก์ด ๋ ์ง('2018-01-01T12:00:00')
beforeAll(() => {
global.Date = ํด๋์ค ํ์ฅ ๋ ์ง {
์์ฑ์() {
๊ฐ๋
์()
์์ ๋ ์ง ๋ฐํ
}
}
})
~~~
@callemo ๋ฐ @iwarner ์ ๋ต๋ณ์ ์ฝ๊ฐ ์ถ๊ฐํ๋ ๊ฒ๊ณผ ๊ฐ์ต๋๋ค.
๋งค๋ฒ ์๋ก์ด ๋ ์ง ์ธ์คํด์ค๋ฅผ ๋ฐํํ๋ฏ๋ก ๋ค์๊ณผ ๊ฐ์ ์์ ์ ์ํํ๊ธฐ ์ฌ์ด ์ค๋ฅ๊ฐ ์ ์ต๋๋ค.
const constantDate = new Date('2018-01-01T12:00:00')
beforeAll(() => {
global.Date = class extends Date {
constructor () {
super(constantDate.getTime())
}
}
})
์ด๋ฅผ ํตํด date ๊ฐ์ฒด(์: setMinutes)๋ฅผ ๋ณ๊ฒฝํ๋ ํจ์๋ฅผ constantDate๋ฅผ ๋ณ๊ฒฝํ์ง ์๊ณ ์ฌ์ฉํ ์ ์์ผ๋ฏ๋ก ์ Date์์ ๋ฐํ๋๋ ๋ ์ง๋ฅผ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
describe('Test', () => {
const constantDate = new Date('2018-01-01T12:00:00')
beforeAll(() => {
global.Date = class extends Date {
constructor () {
super()
return constantDate
}
}
});
it('it should not be possible to mutate the original date but it is.', () => {
const date1 = new Date();
date1.setMinutes(5);
const date2 = new Date();
console.log(date2.getMinutes()); // Will print 5
});
});
์ด๊ฒ์ ์์ ๋ชจ๋ ๋ด์ฉ์ ์ฝ์ ํ ์ฌ์ฉํ๋ ๊ฒ์ ๋๋ค.
let currentDate;
beforeAll(() => {
currentDate = new Date();
const RealDate = Date;
global.Date = jest.fn(() => new RealDate(currentDate.toISOString()));
Object.assign(Date, RealDate);
});
@samboylett ์ด๊ฒ์ด ํฅํ ํ
์คํธ์ ๊ธ๋ก๋ฒ ๋ ์ง๋ฅผ ์๋ง์ผ๋ก afterAll
ํจ์์์๋ ์ฌ์ค์ ํ์ต๋๊น?
๋ค๋ฅธ ํ์ผ์ ํ ์คํธ์๋ ์ํฅ์ ๋ฏธ์น์ง ์์ต๋๋ค. ๋์๊ฒ ํ์ฌ ํ์ผ์ ๋ชจ๋ ๊ฒ์ ๋ชจ์ ๋ ์ง๊ฐ ํ์ํ์ง๋ง ๋์ผํ ํ์ผ์ ํ ์คํธ ์ฌ์ด์ ์ฌ์ค์ ํด์ผ ํ๋ ๊ฒฝ์ฐ beforeEach ๋ฐ afterEach๋ฅผ ์ฌ์ฉํ๊ณ afterEach์์ ๋ค์ ์ค์ ํด์ผ ํฉ๋๋ค.
afterEach(() => {
global.Date = RealDate;
});
@samboylett ๊ฐ์ฌํฉ๋๋ค! ๊ทํ์ ์์ ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ฌ์ฉํ์ฌ ๋ ์ง ํ ์คํธ๋ฅผ ์๋์ํฌ ์ ์์์ต๋๋ค.
const myDate = new Date(2018, 6, 11);
const RealDate = Date;
describe('testcase', () => {
beforeEach(() => {
global.Date = jest.fn(
(...props) =>
props.length
? new RealDate(...props)
: new RealDate(myDate)
);
Object.assign(Date, RealDate);
});
afterEach(() => {
global.Date = RealDate;
});
});
์๋ง๋ jest-date-mock ์ด ํ์ํ ๊ฒ์ ๋๋ค.
ํ ์คํธ ์ผ์ด์ค์ ํ์ฌ ํ์์คํฌํ๋ฅผ ์ ์ดํ๋ โโ๊ฐ๋จํ API๋ฅผ ์ ๊ณตํฉ๋๋ค.
import { advanceBy, advanceTo, clear } 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
});
์์ ์๋ฃจ์ ์ ๋ด ์ฌ์ฉ ์ฌ๋ก๋ฅผ ๋ค๋ฃจ์ง ์์์ต๋๋ค. instanceof ๋ฐ ํน์ ๋ ์ง ์ค์ ์ ๋ํ ์ง์์ด ๋๋ฝ๋ @callemo ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ค์์ ์ํํ์ต๋๋ค.
export function mockDate({year = 2017, month = 9, day = 16}) {
const globalDate = global.Date
global.Date = class MockDate extends Date {
constructor() {
super()
this.setFullYear(year)
this.setMonth(month)
this.setDate(day)
}
}
global.Date.mockRestore = () => global.Date = globalDate
}
@javadoug ๋น์ ์ ๊ฒฝ์ฐ๋ ๋ฌด์์ ๋๊น?
@javadoug ๋น์ ์ ๊ฒฝ์ฐ๋ ๋ฌด์์ ๋๊น?
@hustcc mockDate() instanceof Date === true
.
@javadoug ์ ๋ฒ์ jest-date-mock
์ง์. https://github.com/hustcc/jest-date-mock/pull/7
'๋๋ ํญ์ ์๊ฐ์ ์กฐ๋กฑํ์ง๋ ์์ง๋ง ํ ๋ ๋๋ด์ ๋๋ค` - ์ ๋ช ๋์ @satub
new Date()
๋ฅผ ์กฐ๋กฑํด์ผ ํ์ง๋ง ๋๋จธ์ง Date
๊ธฐ๋ฅ์ ์ ์์ ์ผ๋ก ์๋ํด์ผ ํ์ต๋๋ค. ์ด๊ฒ์ ๋๋ฅผ ์ํด ์ผํ ์๋ฃจ์
์
๋๋ค.
describe('...', () => {
const RealDate = Date;
function mockDate(isoDate) {
global.Date = class extends RealDate {
constructor(...args) {
if (args.length) return new RealDate(...args);
return new RealDate(isoDate);
}
};
}
afterEach(() => {
global.Date = RealDate;
});
it('...', () => {
mockDate('2018-01-01');
// rest of the code
});
})
global.Date์ ํ ๋นํ๋ ค๊ณ ํ ๋๋ง๋ค ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค.
Error: Error: ReferenceError: Date is not defined
at Object.<anonymous>.exportObject.JUnitXmlReporter.self.specDone (/src/node_modules/jasmine-reporters/src/junit_reporter.js:274:33)
at dispatch (/src/node_modules/jest-jasmine2/build/jasmine/report_dispatcher.js:70:26)
at ReportDispatcher.specDone (/src/node_modules/jest-jasmine2/build/jasmine/report_dispatcher.js:62:247)
at Object.specResultCallback (/src/node_modules/jest-jasmine2/build/jasmine/Env.js:411:18)
at Spec.attr.resultCallback (/src/node_modules/jest-jasmine2/build/setup_jest_globals.js:67:24)
at complete (/src/node_modules/jest-jasmine2/build/jasmine/Spec.js:111:10)
at currentRun.then (/src/node_modules/jest-jasmine2/build/jasmine/Spec.js:107:30)
๋ฌธ์ ๋ ํ ์คํธ ์ปจํ ์คํธ์์ ์คํ๋๋ JUnit ๋ฆฌํฌํฐ๋ฅผ ์ฌ์ฉํ๊ณ ์๊ณ ์ต๋ช ํด๋์ค๊ฐ ํ๊ดด๋์ด ์ด๋ฏธ ํ๊ดด๋ Date๋ฅผ ์ฌ์ฉํ๊ณ ์๋ค๋ ๊ฒ์ ๋๋ค.
์, ์์ ๋ชจ๋ ๊ฒ๊ณผ ๊ฐ์ ์ ์์ ์ฌ์ฉํ๋ฉด ์ ์ญ ๋ ์ง๊ฐ ์๋ง์ด ๋ฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋นํ์ค ๋ฆฌํฌํฐ๋ฅผ ์ฌ์ฉํ ๋๋ง ๋ฌธ์ ๊ฐ ๋ฉ๋๋ค.
๊ธฐ์๋ ์๋๋ฐ์ค ๋ด์์ ์คํ๋์ด์๋ ์ ๋ฉ๋๋ค. Jasmine ๊ธฐ์๋ ์๋์ ์ผ๋ก ์ง์๋์ง ์๋ ์ผ๋ถ jasmime ํญ๋ชฉ์ ์ฐ๊ฒฐํ ์ ์์ต๋๋ค.
์, ๊ทธ๋ผ ์ด๋ฐ ์ข ๋ฅ์ ์ฝ๋๋ ์ง์ํ์ง ์๋๋ค๋ ๋ง์์ด์ ๊ฐ์?
const jasmine = global.jasmine;
jasmine.getEnv().addReporter(junitReporter)
์ฌ๊ธฐ์์ ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค.
https://github.com/facebook/jest/blob/f9fd98fd4e38978e96a86f1c8796593cad7ac470/packages/jest-jasmine2/src/jasmine/ReportDispatcher.js#L63 -L72
๋ง์ต๋๋ค, ๋น์ ์ ์ฌ์ฉํด์ผํฉ๋๋ค
https://jestjs.io/docs/en/configuration#reporters -array-modulename-modulename-options.
์: https://github.com/jest-community/jest-junit
@niieani ,
"ํตํฉ" ํ์ด๋จธ ๋ชจ์์ ๋ํ ์๋ฃจ์ ์ ๋ค์๊ณผ ๊ฐ์ด
jest
๋ด์ฅ ํจ์ ๋์lolex
์ฌ์ฉํ๋ ๊ฒ์ ๋๋ค.
๋๋ ๊ทธ ์๋ฅผ ์๋ํ๊ณ ๊ทธ ๊ฒฐ๊ณผ ๋ด ํ ์คํธ๊ฐ ์์ํ ์ค๋จ๋์์ต๋๋ค([email protected]์ ์ฌ์ฉํ๋ CRA์์). Jest์ ํจ๊ป lolex๋ฅผ ์ฌ์ฉํ์ฌ ์ฑ๊ณตํ ์ฌ๋์ด ์์ต๋๊น?
@kentcdodds ๋ ๋๋ด ๊ฐ์ง ํ์ด๋จธ๋ฅผ ๋์์ ์ฌ์ฉํ์ง ์๋๋ก ํฉ๋๋ค. ์ฌ์ ํ ๋ฉ์ถ๋ฉด ์ฌ์์ฐ์ ๋ฌธ์ ๋ฅผ ์ผ์ผํค์๊ฒ ์ต๋๊น? ๋กค๋ ์ค๋ ํ์คํ ์๋ํด์ผํฉ๋๋ค
์, ๊ณ ๋ฆฝ๋ ์ํฉ์์๋ ์ ์๋ํ๋ฏ๋ก ๋ค๋ฅธ ๊ณณ์์ ์ด์ํ ์ผ์ ํ๊ณ ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ๊ฐ์ฌ ํด์!
์ด๋ฌํ ๊ฒฝ์ฐ๋ง ์กฐ๋กฑํด์ผ ํ๋ ๊ฒฝ์ฐ:
new Date()
new Date('2018-09-20T23:00:00Z')
const currentDate = new Date('2018-09-20T23:00:00Z');
Date = class extends Date {
constructor(date) {
if (date) {
return super(date);
}
return currentDate;
}
}
์ด๊ฒ์ ์์ ๋ชจ๋ ๋ด์ฉ์ ์ฝ์ ํ ์ฌ์ฉํ๋ ๊ฒ์ ๋๋ค.
let currentDate; beforeAll(() => { currentDate = new Date(); const RealDate = Date; global.Date = jest.fn(() => new RealDate(currentDate.toISOString())); Object.assign(Date, RealDate); });
@samboylett ๊ฐ์ฌ
์ด๊ฒ์ new Date()๋ฅผ ์กฐ๋กฑํ๋ ๋ฐ ํจ๊ณผ์ ์ด์์ต๋๋ค.
@petromoldovan ์ ํ์คํ ์ต๊ณ ์ ๋ต๋ณ์ ๋๋ค.
ํ
์คํธ๊ฐ ๋๋ ๋ mockRestore
์ ๋ํ ํธ์ถ์ ์ถ๊ฐํ์ฌ ์๋ ๋ ์ง๋ฅผ ๋ณต์ํฉ๋๋ค.
const dateNowMockFn = jest.spyOn(Date, 'now').mockImplementation(() => 1479427200000);
// ... code with tests
dateNowMockFn.mockRestore();
๋ชจ์ ๊ฐ์ฒด๊ฐ ์ ํด๋์ค ์ค ํ๋ ๋์ Date ์ธ์คํด์ค๋ฅผ ๋ฐํํ๋๋ก ํ๋ ค๋ ๊ฒฝ์ฐ์ ๋๋นํ์ฌ @vcarel ์๋ฃจ์ ์ ์ฝ๊ฐ ๊ฐ์
const RealDate = Date
const mockDate = (isoDate) => {
global.Date = class extends RealDate {
constructor () {
return super(isoDate)
}
}
}
afterEach(() => {
global.Date = RealDate
})
๋๋ ์ฌ๊ธฐ์์ ํ์ฐจ๋ฅผ ๋ฐ๋ผ๋ณด๊ณ ์์์ง ๋ชจ๋ฅด์ง๋ง ์ค๋๋ ๊ฒฉ์ธ์ ์ง์ ํ ๊ฐ์น๊ฐ ์์ต๋๋ค .
const myFunc = (msg, date = new Date()) => console.log(`${msg}! ${date}`);
์ด์ ํ๋ก๋์ ์ฝ๋์์ ๊ธฐ๋ณธ๊ฐ์ ํ์ฉํ ์ ์์ต๋๋ค.
myFunc("Hello"); // => Hello! Fri Mar 22 2019 21:11:26 GMT-0400 (EDT)
๊ทธ๋ฆฌ๊ณ ํ ์คํธ ์ฝ๋์์ ๋ ์ง๋ฅผ ๋ช ์์ ์ผ๋ก ์ ๋ฌํ์ฌ ์ด๋ฅผ ์กฐ๋กฑํ ์ ์์ต๋๋ค.
myFunc("Hello", dateObj) // => Hello! ...
@yawaramin ์ด๊ฒ์ ๋ํด์๋ ํ์คํ ๋ช ๊ฐ์ง ๋ค๋ฅธ ๊ด์ ์ด ์์ต๋๋ค. ํ ์คํธ๊ฐ ์ ํ๋ฆฌ์ผ์ด์ ์ฝ๋๋ฅผ ์ํด ์กด์ฌํด์ผ ํ๋ค๊ณ ๋ฏฟ๋ ์ง์์ด ์๊ณ , ๊ผฌ๋ฆฌ๊ฐ ๊ฐ๋ฅผ ํ๋๋ ๊ณผ๊ฑฐ ์ง์ ์ด ์์ต๋๋ค(Pete Hunt๋ ์ด์ ๋ํด ๊ฐํ ์๊ฒฌ ์ ๊ฐ์ง๊ณ ์์ต๋๋ค)
์ ์ํ ๋ฐฉ๋ฒ์ด ์ ํจํ ์ต์ ์ด ์๋๋ผ๊ณ ๋งํ๋ ๊ฒ์ด ์๋๋ผ ์ํฉ์ ๋ฐ๋ผ ์ ์ ํ ๋ฐฉ๋ฒ์ผ๋ก ์ ์๋ ์ ์์ต๋๋ค.
@cheapsteak ์ํฉ์ ์ ์ ์ฑ์ด ์ฌ๋ฌผ์ ๊ธฐ๋ณธ ์ํ๋ผ๊ณ ์๊ฐํฉ๋๋ค. ์ฌ๋๋ค์๊ฒ ํญ์ ํ ์คํธ ๊ฐ๋ฅ์ฑ์ ๊ฐ์ ํ ๊ธฐํ๊ฐ ์์ผ๋ฉฐ ๊ทธ๋ ๊ฒ ํ๋ฉด ์ผ๋ฐ์ ์ผ๋ก ์ ์ง ๊ด๋ฆฌ ๊ฐ๋ฅ์ฑ์ด ํฅ์๋๋ค๋ ์ ์ ๋ถ๋๋ฝ๊ฒ ์๊ธฐ์ํค๋ ๊ฒ์ ๋์์ง ์์ต๋๋ค :-)
ํ์ด๋จธ๋ฅผ ๋ฐ์กํ ๋ ๋๋ด์ ํ์ฌ ์๊ฐ์ ์ป๋ ๋ฐฉ๋ฒ์ด ์์ต๋๊น? jest.now์ ๊ฐ์ ๊ฒ?
Date.now()์ ๋ํ ํ์ด๋จธ์ ํธ์ถ์ด ์๋ค๊ณ ๊ฐ์ ํฉ๋๋ค. jest.runAllTimers()๋ฅผ ํธ์ถํฉ๋๋ค. ํ์ด๋จธ ์ฝ๋ฐฑ์ด ์คํ๋๊ณ ์๋ฎฌ๋ ์ด์ ๋ ์๊ฐ์ ํ์ธํ ์ ์๋๋ก jest.spyOn(Date, 'now').mockImplementation(() => something )์ ํธ์ถํ ์ ์๋ค๋ฉด ๋ฉ์ง
๋๋
Date.now()
๋ฅผ ์กฐ๋กฑํด์ผ ํ๋ค๊ตฌ์ฑ์์ ๋๋ ํ ์คํธ๊ฐ ์๋ํ๊ธฐ ์ ์ ์๋ ์ค์ ์ค์ ํ์ญ์์ค.
jest.spyOn(Date, 'now').mockImplementation(() => 1479427200000)
๋ง์ ์ฌ๋๋ค์๊ฒ ํจ๊ณผ๊ฐ ์์ง๋ง ๋์๊ฒ๋ ๊ทธ๋ ์ง ์์ ๋ฐฉ๋ฒ์ด ์ฌ๋ฏธ์์ต๋๋ค. ํ .
๋ฌด์จ ์ผ์ด ์ผ์ด๋๊ณ ์๋์ง ๋ชจ๋ฅด๊ฒ ์ง๋ง Date
์ฌํ ๋นํ๋ ๋ฐฉ๋ฒ์ ์๊ด์์ด Date.now()
ํญ์ ์กด์ฌํ๋ฉฐ ํญ์ ์ ํจํ ๊ฐ์ ๋ฐํํฉ๋๋ค.
Date.now = null
๋ ์๋ฌด ์์
๋ ์ํํ์ง ์์ต๋๋ค.
global.Date.now = null
๋ ์๋ฌด ์์
๋ ์ํํ์ง ์์ต๋๋ค.
jest.spyOn(Date, 'now').mockImplementation(() => 1479427200000);
๋ ์๋ฌด ์์
๋ ์ํํ์ง ์์ต๋๋ค.
lolex
์ค์น ๋ฐ ์ฌ์ฉ์ ์๊ฐ ์ด๊ณผ ์ ์๋ํ์ง๋ง Date.now()
์๋ ์ํฅ์ ๋ฏธ์น์ง ์์ต๋๋ค.
MockDate
๋ ํจ๊ณผ๊ฐ ์์ต๋๋ค.
๋๋ ๋ถ๋ช ํ ๊ฒ์ ๋์น๊ณ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ๋ค๋ฅธ ์ข ์์ฑ์ด ๋ญ๊ฐ๋ฅผ ํ๊ณ ์๋ ๊ฒ ๊ฐ์ต๋๋ค... ๋๋ฌด ํผ๋์ค๋ฝ์ต๋๋ค.
@mherodev ๋ ํ ์คํธ๋ฅผ ํ์ธํฉ๋๋ค. ํ ์คํธ ๊ธฐ๋ฅ์ด ์คํ๋๊ธฐ ์ ์ / ๊ตฌ์ฑ ์์๊ฐ ๋ ๋๋ง๋๊ธฐ ์ ์ ๋ชจ์ ๋ ์ง๋ฅผ ์ฌ์ฉํฉ๋๊น?
ํ ์คํธ ๋ธ๋ก ๋ด์์ ๋๋ ๋ค์๊ณผ ๊ฐ์ ์ผ์ํ๊ณ ์์ต๋๋ค ...
Date.now = () => 1;
Date = null;
global.Date = null;
console.log(`Date.now()`, Date.now()); // Date.now() 1560239936091
๊ทธ๋ฌ๋ ๊ทธ ์ฌ์ ์๋ ์๋ฌด ๊ฒ๋ ํ์ง ์์ต๋๋ค. ๋๋ ๊ทธ๊ฒ์ด ๋งค์ฐ ํผ๋์ค๋ฝ๋ค๊ณ ์๊ฐํ๋ค.
๋๋ Hugo์ ํํ ๋ฆฌ์ผ์ ๋ฐ๋๊ณ ๊ฒฐ๊ตญ ๋ค์์ ์ํํ์ต๋๋ค.
// @ts-ignore
.spyOn(global.Date, 'constructor')
.mockImplementationOnce(() => new Date('2019-06-19T00:07:19.309Z'))
๋ฐ๋ผ์ new Date()
๋ ํญ์ new Date('2019-06-19T00:07:19.309Z')
๋ฐํํฉ๋๋ค.
์
๋ฐ์ดํธ: ๋ด ํ๊ฒฝ์์ babel์ด ์ด๋ป๊ฒ ๋ณํ๋๋์ง์ ๋ํ ๋ฒ๊ทธ๋ก ์ธํด ๋ด Date ๋ชจ์๊ฐ ์๋ํ์ง ์๋ ๊ฒ ๊ฐ์ต๋๋ค. @babel/runtime-corejs2
์ฌ์ฉ ๋ฐฉ๋ฒ๊ณผ ๊ด๋ จ๋ ๊ฒ
๊ถ๊ทน์ ์ธ ์๋ฃจ์ : jest-date-mock .
jest ์๋์ package.json์์ setupFiles ๋ฐฐ์ด์ ๋ง๋ค๊ณ ๋ฐฐ์ด์ jest-date-mock์ ์ถ๊ฐํฉ๋๋ค.
{
"jest": {
"setupFiles": ["./__setups__/other.js", "jest-date-mock"]
}
}
ํ ์คํธ ์ผ์ด์ค์ ํ์ฌ ํ์์คํฌํ๋ฅผ ์ ์ดํ๋ โโ๊ฐ๋จํ API๋ฅผ ์ ๊ณตํฉ๋๋ค.
import { advanceBy, advanceTo, clear } 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
});
๋ด ์๊ฐ์: ๋ค๋ฅธ ๋ชจ๋ ์๋ฃจ์ ์ ์ฒด๊ณ์ ์ด์ง ์๊ฑฐ๋ ์ผ์์ ์ด์ง ์์ต๋๋ค.
babel ๋ณํ์ด ์ด์ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ๊นจ๋ ๊ฒ์ฒ๋ผ ๋ณด์ ๋๋ค.
๋ด ์๋ฃจ์
์ setupMockDate.js
๋ผ๋ ์ ํ์ผ์ ์ถ๊ฐํ๋ ๊ฒ์
๋๋ค.
const mockDate = DateClass => {
function Mock(...args) {
return args.length === 0
? new DateClass(Mock.now())
: new DateClass(...args)
}
Object.setPrototypeOf(Mock, DateClass)
Mock.prototype = DateClass.prototype
let now
Mock.now = () => now === undefined ? DateClass.now() : now
Mock.mockNow = value => now = value
Mock.mockRestore = () => Mock.mockNow()
return Mock
}
global.Date = mockDate(Date)
setupFilesAfterEnv
ํญ๋ชฉ์ jest.config.js
(๋๋ ์ด์ jest ๋ฒ์ ์ ๊ฒฝ์ฐ setupFiles
)์ '<rootDir>/jest/setupMockDate.js'
ํฉ๋๋ค.
์ด์ , ๋น์ ์ ์คํํ ์ ์์ต๋๋ค
Date.mockNow(10)
expect(Date.now()).toBe(10)
Date.mockRestore()
expect(Date.now()).not.toBe(10)
Sinon์ ์ ์๊ฒ ์ ์๋ํฉ๋๋ค. https://sinonjs.org/releases/v1.17.7/fake-timers/
ํํฐ์ ๋ฆ์์ง๋ง jest์๋ ํ์ํ ๋ชจ๋ ๊ธฐ๋ฅ์ด ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
describe('how to mock date.now()', function() {
beforeEach(() => {
this.timestamp = 0
global.Date.now = jest.fn().mockImplementation(() => this.timestamp)
})
afterEach(() => {
jest.clearAllMocks()
})
it('can advance in time', () => {
const then = Date.now()
this.timestamp += 1000
const now = Date.now()
expect(now - then).toBe(1000)
})
๋๋ vue-moment์ jest๋ฅผ ์ฌ์ฉํ๊ณ ์์ผ๋ฉฐ ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ด ์ํํ๋ ๊ฒ์ ๋๋ค.
import { mount, createLocalVue } from '@vue/test-utils';
import TripList from 'components/trip-list.vue';
const localVue = createLocalVue();
localVue.use(require('vue-moment'));
describe('TripList', () => {
it('text shows current date', () => {
const myDate = new Date(2019, 5, 5);
const wrapper = mount(TripList, {
localVue,
});
wrapper.vm.$moment.now = () => myDate;
wrapper.vm.$forceUpdate();
expect(wrapper.html()).toContain('Thu, Oct 3rd');
});
})
ES6 ์ฌ์ฉ
const fixedDate = new Date('2019-03-1');
const RealDate = Date;
beforeEach(() => { Date.now = () => fixedDate; });
afterEach(() => { global.Date = RealDate; });
Date.now()
const dateSpy = jest.spyOn(Date, 'now');
dateSpy.mockReturnValue(TIMESTAMP);
์ด๊ฒ์ผ๋ก ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ ๋ค๋ฅธ ์ฌ๋์ ๊ฒฝ์ฐ ์ ์ญ Date ๊ฐ์ฒด์ ์์ฑ์ ์ด์ธ์ ์์ฑ์ด ์๊ธฐ ๋๋ฌธ์ ๋ช ๊ฐ์ง ๋ฌธ์ ๊ฐ ์์์ต๋๋ค. ๋๋ ๋ค์์ ์ํํ๋ค.
const DATE_TO_USE = new Date('2016'); const _Date = Date; global.Date = jest.fn(() => DATE_TO_USE); global.Date.UTC = _Date.UTC; global.Date.parse = _Date.parse; global.Date.now = _Date.now;
๋๋ ์ ์ฒด Date ํด๋์ค๋ฅผ ์กฐ๋กฑํ๊ณ ์ถ์๊ณ @kristojorg๊ฐ ์ ์ํ ๋ฐฉ๋ฒ์ด ์ด์์ ์ผ๋ก ๋ณด์์ต๋๋ค.
๋๋ ํ์คํ์ง์ด ๊ทธ๊ฒ์ ํ ์์๋ ์ ์ ํ ๋ฐฉ๋ฒ์ด์ง๋ง,์ด ์๋ฃจ์ ์ @nilobarp์์ ์ธ๊ธ ํ ๋ฐ์ ๊ฐ์ด ํ์ดํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ์ฌ ํ์ดํ์ ๋ฒ๊ธ์ ์๋ํ๋ ๊ฒฝ์ฐ์ ๋๋ค :
describe('Mock Date', () => {
const realDateNow = Date.bind(global.Date);
beforeAll(() => {
// Fix the time to 2020-1-1 1hr:1min:1sec in order to match
// snapshots for the DownloadConfirmDialog component.
const fixedDate = new Date(2020, 0, 1, 1, 1, 1);
const d = Date;
// This will only mock any Date objects instantiated with new
// and not Date.now().
const _global: NodeJS.Global = global;
_global.Date = jest.fn(() => fixedDate);
_global.Date.parse = d.parse;
_global.Date.UTC = d.UTC;
_global.Date.now = d.now;
});
it('shows mocked date', () => {
// Shows 2020-01-01T01:01:01.000Z as the current Date
// for an instantiated Date object.
console.log(new Date().toISOString());
});
afterAll(() => {
// Reverts to the current Date object.
global.Date = realDateNow;
console.log(new Date().toISOString());
});
});
์ด๊ฒ์ ์๋ก์ด Date
๊ฐ์ฒด๋ฅผ ์ธ์คํด์คํํ ๋๋ง ์๋ํ๊ณ Date.now()
์์๋ ์๋ํ์ง ์๋๋ค๋ ์ ์ ์ธ๊ธํ ๊ฐ์น๊ฐ ์์ต๋๋ค. Date.now์ ๋ํ
ํ ์คํธ ๋ธ๋ก ๋ด์์ ๋๋ ๋ค์๊ณผ ๊ฐ์ ์ผ์ํ๊ณ ์์ต๋๋ค ...
Date.now = () => 1; Date = null; global.Date = null; console.log(`Date.now()`, Date.now()); // Date.now() 1560239936091
๊ทธ๋ฌ๋ ๊ทธ ์ฌ์ ์๋ ์๋ฌด ๊ฒ๋ ํ์ง ์์ต๋๋ค. ๋๋ ๊ทธ๊ฒ์ด ๋งค์ฐ ํผ๋์ค๋ฝ๋ค๊ณ ์๊ฐํ๋ค.
๋์ผํ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. ์ด ๋ฌธ์ ์์ ๋ฐ๊ฒฌ๋ ์ ์ฒด ์ฝ๋ ์์ ๋ฅผ ํ ์คํธํ์ง๋ง ์๋ฌด ๊ฒ๋ ํจ๊ณผ๊ฐ ์์์ต๋๋ค. mock์ ๋ฌด์๋ ๊ฒ์ผ๋ก ๋ณด์ ๋๋ค.
๋ฌธ์ ๋ฅผ ์ด๋ป๊ฒ ํด๊ฒฐํ์ต๋๊น?
์ฐ๋ฆฌ๋ ๋ํ Babel์ ์ฌ์ฉํ๊ณ ์์ผ๋ฏ๋ก ์ด๊ฒ ์ญ์ ๊ด๋ จ์ด ์์ ์ ์์ต๋๋ค.
ํ ์คํธ ๋ธ๋ก ๋ด์์ ๋๋ ๋ค์๊ณผ ๊ฐ์ ์ผ์ํ๊ณ ์์ต๋๋ค ...
Date.now = () => 1; Date = null; global.Date = null; console.log(`Date.now()`, Date.now()); // Date.now() 1560239936091
๊ทธ๋ฌ๋ ๊ทธ ์ฌ์ ์๋ ์๋ฌด ๊ฒ๋ ํ์ง ์์ต๋๋ค. ๋๋ ๊ทธ๊ฒ์ด ๋งค์ฐ ํผ๋์ค๋ฝ๋ค๊ณ ์๊ฐํ๋ค.
๋์ผํ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. ์ด ๋ฌธ์ ์์ ๋ฐ๊ฒฌ๋ ์ ์ฒด ์ฝ๋ ์์ ๋ฅผ ํ ์คํธํ์ง๋ง ์๋ฌด ๊ฒ๋ ํจ๊ณผ๊ฐ ์์์ต๋๋ค. mock์ ๋ฌด์๋ ๊ฒ์ผ๋ก ๋ณด์ ๋๋ค.
๋ฌธ์ ๋ฅผ ์ด๋ป๊ฒ ํด๊ฒฐํ์ต๋๊น?
์ฐ๋ฆฌ๋ ๋ํ Babel์ ์ฌ์ฉํ๊ณ ์์ผ๋ฏ๋ก ์ด๊ฒ ์ญ์ ๊ด๋ จ์ด ์์ ์ ์์ต๋๋ค.
@warpdesign ์ด ์๋ฃจ์ ์ TypeScript์ Jest์ ํจ๊ป ์๋ํ๋ ๊ฒ ๊ฐ์ต๋๋ค.
describe('Mock Date.now', () => {
// Bind to the original Date so we can set it back after all tests are finished.
const realDateNow = Date.now.bind(global.Date);
beforeAll(() => {
// Return 1 millisecond when calling Date.now() in tests.
const dateNowStub = jest.fn(() => 1);
global.Date.now = dateNowStub;
});
it('shows mocked date', () => {
console.log(Date.now()); // Returns 1.
});
afterAll(() => {
// Set back to the original Date object.
global.Date.now = realDateNow;
console.log(Date.now()); // Returns current time in milliseconds.
});
});
๊ถ๊ทน์ ์ธ ์๋ฃจ์ : jest-date-mock .
- ์ค์น
jest ์๋์ package.json์์ setupFiles ๋ฐฐ์ด์ ๋ง๋ค๊ณ ๋ฐฐ์ด์ jest-date-mock์ ์ถ๊ฐํฉ๋๋ค.
{ "jest": { "setupFiles": ["./__setups__/other.js", "jest-date-mock"] } }
- ์ฉ๋ฒ
ํ ์คํธ ์ผ์ด์ค์ ํ์ฌ ํ์์คํฌํ๋ฅผ ์ ์ดํ๋ โโ๊ฐ๋จํ API๋ฅผ ์ ๊ณตํฉ๋๋ค.
import { advanceBy, advanceTo, clear } 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 });
๋ด ์๊ฐ์: ๋ค๋ฅธ ๋ชจ๋ ์๋ฃจ์ ์ ์ฒด๊ณ์ ์ด์ง ์๊ฑฐ๋ ์ผ์์ ์ด์ง ์์ต๋๋ค.
๊ฐ์ฌํฉ๋๋ค!
๋๋ Hugo์ ํํ ๋ฆฌ์ผ์ ๋ฐ๋๊ณ ๊ฒฐ๊ตญ ๋ค์์ ์ํํ์ต๋๋ค.
// @ts-ignore .spyOn(global.Date, 'constructor') .mockImplementationOnce(() => new Date('2019-06-19T00:07:19.309Z'))
๋ฐ๋ผ์
new Date()
๋ ํญ์new Date('2019-06-19T00:07:19.309Z')
๋ฐํํฉ๋๋ค.
์ด ์ฌ๋์ ๋ฌด์จ ๊ฐ์๋ฆฌ์ผ. U๋ Hugo์ ํํ ๋ฆฌ์ผ์ ๋งํ๊ณ Hugo๋ ๋น์ ์ ํํ ๋ฆฌ์ผ์ ๋งํฉ๋๋ค.... ์ ๋ฐ ์ฐ๋ฆฌ๋ฅผ ์ค๋ํ์ง ๋ง์ญ์์ค.
Jest 26์ ์ต์ ๊ฐ์ง ํ์ด๋จธ๋ฅผ ์ฌ์ฉํ์ฌ Date
์กฐ๋กฑ์ ์ง์ํฉ๋๋ค. https://jestjs.io/blog/2020/05/05/jest-26#new -fake-timers
TS์์ Date ์์ฑ์๋ฅผ ์กฐ๋กฑํ๋ ๋ฐ ์ด๋ ค์์ ๊ฒช๊ณ ์๋ค๋ฉด ๋ค์์ ์๋ํ์ญ์์ค.
const mockDate = new Date('Tue, 23 Jun 2020 14:34:56');
const RealDate = Date;
(global as any).Date = class extends RealDate {
constructor() {
super();
return mockDate;
}
};
// test some date related functionality
global.Date = RealDate;
Jest 26์ ์ต์ ๊ฐ์ง ํ์ด๋จธ๋ฅผ ์ฌ์ฉํ์ฌ
Date
์กฐ๋กฑ์ ์ง์ํฉ๋๋ค. https://jestjs.io/blog/2020/05/05/jest-26#new -fake-timers
@SimenB ํ๋ฅญํ๊ณ ๋ฐฉ๊ธ v26์ผ๋ก ์ ๋ฐ์ดํธํ์ง๋ง
@gregveres ๋ค์์ ์์คํ
์๊ฐ( Date
๋ฉ์๋)์ ๊ณ ์ ๋ ์ง๋ก ์ค์ ํ๊ณ ํด๋น ์๊ฐ์ ์๋น๊ธฐ๋ ๊ฒ์ ์ฒ๋ฆฌํ๋ ์์ ํ
์คํธ ๋ชจ์์
๋๋ค.
const FIXED_SYSTEM_TIME = '2020-11-18T00:00:00Z';
describe('Set Fixed Date', () => {
beforeEach(() => {
jest.useFakeTimers('modern');
jest.setSystemTime(Date.parse(FIXED_SYSTEM_TIME));
});
afterEach(() => {
jest.useRealTimers();
});
it('Should reflect fixed date', () => {
expect(new Date().toISOString()).toEqual(FIXED_SYSTEM_TIME);
const MS_TO_ADVANCE = 5000;
jest.advanceTimersByTime(MS_TO_ADVANCE);
expect(new Date().toISOString()).toEqual(new Date(Date.parse(FIXED_SYSTEM_TIME) + MS_TO_ADVANCE).toISOString());
});
});
_์
๋ฐ์ดํธ: ์๋ @alexdanilowicz ์ ๋๊ธ๋น afterEach()
ํฌํจ._
_์ด ์ค๋ ๋๊ฐ ์ค๋๋๊ณ ์ธ๊ธฐ ์๋ stackoverflow ๊ฒ์๋ฌผ์ ์ฐ๊ฒฐ๋จ์ ๋ฐ๋ผ ^ ๊ตต๊ฒ ํ์_
@seansullivan ๊ต์ฅํฉ๋๋ค! ์ฐธ๊ณ ๋ก, ์ ๊ฐ ํ๋ ธ๋ค๋ฉด ์ ์ ํด ์ฃผ์ธ์. ํ์ง๋ง ์ฌ์์ afterEach(๋๋ afterAll)๋ฅผ ์ถ๊ฐํ์ฌ ๋ ์ง๋ฅผ ๋ค์ ํ์ค๋ก ๋๋๋ฆฌ๋ ๊ฒ์ด ์ข์ ๊ฒ ๊ฐ์ต๋๋ค. ๋จ์ง ์์ ํ๊ธฐ ์ํด์์ ๋๋ค.
describe('Test', () => {
// to avoid race conditions between expected and actual date values
beforeAll(() => {
jest.useFakeTimers('modern'); // tell Jest to use a different timer implementation.
jest.setSystemTime(new Date('20 Aug 2020 00:12:00 GMT').getTime())
});
afterAll(() => {
// Back to reality...
jest.useRealTimers();
});
@alexdanilowicz ์๋ฒฝํฉ๋๋ค. ์, ๋๋ ๋ด ์์ ์ ๋ฆฌ๋ฅผ ํฌํจํ๋ ๊ฒ์ ๊ฒ์๋ฆฌํ์ต๋๋ค. ์ด ์ค๋ ๋๋ฅผ ์ฐพ๋ ๋ชจ๋ ์ฌ๋์ด ์จ์ ํ ์ํ๋ฅผ ์ ์งํ ์ ์๋๋ก afterEach()
๋ก ์
๋ฐ์ดํธํ๊ฒ ์ต๋๋ค. ๊ฐ์ฌ ํด์!
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
์ด๊ฒ์ผ๋ก ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ ๋ค๋ฅธ ์ฌ๋์ ๊ฒฝ์ฐ ์ ์ญ Date ๊ฐ์ฒด์ ์์ฑ์ ์ด์ธ์ ์์ฑ์ด ์๊ธฐ ๋๋ฌธ์ ๋ช ๊ฐ์ง ๋ฌธ์ ๊ฐ ์์์ต๋๋ค. ๋๋ ๋ค์์ ์ํํ๋ค.