正如标题所述,在模拟Jest中对new Date()
构造函数的调用时,我遇到了一些困难。我正在模拟此调用,以通过返回特定的日期时间来确保测试不会失败。但是,由于在我正在测试的函数中两次调用了日期构造函数,因此第二次调用也对其实现进行了模拟,因此不应模拟第二次调用。
我在下面提供了一个上下文示例,它是一个小函数,可以返回直到明天的秒数,因此需要模拟一致的 now 时间。
任何帮助都会有很大帮助,我已经通过Stack Overflow和Jest文档用尽了所有搜索。
谢谢。
功能
function getSecondsToTomorrow() {
// This call needs to be mocked to always return the same date time
const now = new Date();
// This call should not be mocked
const tomorrow = new Date(
now.getFullYear(),
now.getMonth(),
now.getDate() + 1,
);
return Math.round( (tomorrow - now) / 1000);
}
测试
describe("getSecondsToTomorrow()", () => {
let result, mockDate, now;
beforeAll(() => {
now = new Date(2020, 7, 3, 23, 0, 0);
mockDate = jest.spyOn(global, "Date").mockImplementation(() => now);
result = getSecondsToTomorrow();
});
afterAll(() => {
mockDate.mockRestore();
});
it("should return the number of seconds until tomorrow, from the time the function was called", () => {
// We mock the date to be 2300, so the return should be 1 hour (3600 seconds)
expect(result).toBe(3600);
});
});
更新
尽管我仍然没有找到问题的具体答案,但已经找到了解决方法。即使用Jest的mockImplementationOnce
方法,我可以在对new Date()
的第一次调用中模拟日期时间,并在第二次调用中将任何参数作为默认的ockImplementation传递。
describe("getSecondsToTomorrow()", () => {
let result, mockDate, now, dateClone;
function setUpDateMock(now) {
return jest
.spyOn(global, "Date")
.mockImplementation((...args) => new dateClone(...args))
.mockImplementationOnce(() => now)
}
beforeAll(() => {
dateClone = Date;
now = new Date(2020, 7, 3, 23, 0, 0);
mockDate = setUpDateMock(now);
result = getSecondsToTomorrow();
});
afterAll(() => {
mockDate.mockRestore();
});
it("should return the number of seconds until tomorrow, from the time the function was called", () => {
expect(result).toBe(3600);
});
});