Jest mock moment()返回特定日期



我知道这个问题已经被问了很多次了。

但我找不到适合我情况的。

我想模拟moment((来返回一个特定的日期。

首先,我被嘲笑

jest.mock("moment", () => {
return (date: string) =>
jest.requireActual("moment")(date || "2021-01-01T00:00:00.000Z");
});

但我使用了矩的一些性质(例如moment.duration()...(,所以当这样模拟时,它不起作用。

下一步我尝试通过几种方式模拟Date.now

jest.spyOn(Date, "now").mockReturnValue(+new Date("2021-01-01T00:00:00.000Z"));
Date.now = jest.fn(() => +new Date("2021-01-01T00:00:00.000Z")

但是在执行此操作时,当调用moment()时,它会返回一个无效的日期。

我不确定我做错了什么。

模拟moment()函数及其返回值。使用jest.requireActual('moment')获取原始模块。将其属性和方法复制到模拟的属性和方法。

例如

index.js:

import moment from 'moment';
export function main() {
const date = moment().format();
console.log('date: ', date);
const duration = moment.duration(2, 'minutes').humanize();
console.log('duration: ', duration);
}

index.test.js:

import { main } from '.';
import moment from 'moment';
jest.mock('moment', () => {
const oMoment = jest.requireActual('moment');
const mm = {
format: jest.fn(),
};
const mMoment = jest.fn(() => mm);
for (let prop in oMoment) {
mMoment[prop] = oMoment[prop];
}
return mMoment;
});
describe('68209029', () => {
it('should pass', () => {
moment().format.mockReturnValueOnce('2021-01-01T00:00:00.000Z');
main();
});
});

测试结果:

PASS  examples/68209029/index.test.js (8.914 s)
68209029
✓ should pass (20 ms)
console.log
date:  2021-01-01T00:00:00.000Z
at Object.main (examples/68209029/index.js:5:11)
console.log
duration:  2 minutes
at Object.main (examples/68209029/index.js:7:11)
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        9.726 s

看看日志,我们正确地模拟了moment().format()的返回值,并继续使用moment.duration(2, 'minutes').humanize()方法的原始实现。

@showloadp2答案的补充。

只是想添加另一种方式:

jest.mock("moment", () => {
// Require actual moment
const actualMoment = jest.requireActual("moment");
// Mocking moment func: 
// moment() => return specific date, and it won't affect moment(date) with param.
const mockMoment: any = (date: string | undefined) =>
actualMoment(date || "2021-01-01T00:00:00.000Z");
// Now assign all properties from actual moment to the mock moment, so that they can be used normally
for (let prop in actualMoment) {
mockMoment[prop] = actualMoment[prop];
}
return mockMoment;
});

你也可以这样做

jest.mock('moment', () => {
const originalModule = jest.requireActual('moment')
return {
__esModule: true,
...originalModule,
default: () => originalModule('2023-06-23')
}
})

我在笑话v29.3 上尝试

最新更新