使用 jest moment().format 的模拟返回当前日期而不是模拟日期

Mock using jest moment().format is returning current date instead of mocked date

我正在尝试使用 jest 模拟 moment 库的格式函数。我的测试文件中有以下代码。

app.spec.js:

jest.mock('moment', () => {
    const moment = () => ({
        format: () => mockedTime
    });
    moment.tz = {
        setDefault: () => {}
    };
    moment.tz.setDefault('Asia/Singapore');
    return moment;
});

app.js:

moment.tz.setDefault(TIMEZONE);
moment().format('YYYYMMDD');

它正在生成以下输出:

 - "date": "20190825", // mocked date
 - "date": "20190827", // result value

预期的输出应该是:

 - "date": "20190825", // mocked date
 - "date": "20190825", // result value

任何人都可以帮我指出代码有什么问题吗?

谢谢。

您不是在 moment 上调用 format,而是在 moment() 的结果上调用 format

    jest.doMock('moment', () => {
        const moment = () => ({
            format: () => mockedTime,
        })

        moment.tz = { // prevent 'Cannot read property of undefined'
            setDefault: () => {},
        }

        return moment
    });

这样可以吗,还是您的应用中需要更复杂的模拟,包括时区?

模拟 'moment-timezone' 而不是 'moment 修复它。

jest.mock('moment-timezone', () => {
    const moment = () => ({
        format: () => mockedTime
    });
    moment.tz = {
        setDefault: () => {}
    };
    moment.tz.setDefault('Asia/Singapore');
    return moment;
});

可用的答案不适用于我的情况。模拟底层 Date.now 函数但是按照这个答案建议的那样做了:

Date.now = jest.fn(() => new Date('2020-05-13T12:33:37.000Z'));