Jest.js 如何模拟javascipt new Date从浏览器控制台返回不同的日期

qyswt5oh  于 6个月前  发布在  Jest
关注(0)|答案(4)|浏览(73)

我使用的一个网站在不同的日期显示不同的内容。在JavaScript中,它使用new Date()来确定当前日期,它使用该日期来确定显示哪些内容。
如果我想查看不同日期的内容,我可以更改系统时间。但是,这很繁琐,而且会干扰其他应用程序。我正在尝试找出是否可以在浏览器的javascipt控制台中运行一些代码,以模拟new Date()来返回我选择的日期
我看到有一些问题,讨论创建一个间谍日期与笑话,但我没有看到一种方法来嘲笑这在我的浏览器控制台

vltsax25

vltsax251#

可以用你自己的函数来替换Date函数,以提供你想要的结果,但是在页面使用它之前这样做会很棘手,除非你写一个浏览器扩展。
基本位是(见注解):

// Save the original `Date` function
const OriginalDate = Date;
// Replace it with our own
Date = function Date(...args) {
    // Called via `new`?
    if (!new.target) {
        // No, just pass the call on
        return OriginalDate(...args);
    }
    // Determine what constructor to call
    const ctor = new.target === Date ? OriginalDate : new.target;
    // Called via `new`
    if (args.length !== 0) {
        // Date constructor arguments were provided, just pass through
        return Reflect.construct(ctor, args);
    }
    // It's a `new Date()` call, mock the date we want; in this
    // example, Jan 1st 2000:
    return Reflect.construct(ctor, [2000, 0, 1]);
};
// Make our replacement look like the original (which has `length = 7`)
// You can't assign to `length`, but you can redefine it
Object.defineProperty(Date, "length", {
    value: OriginalDate.length,
    configurable: true
});

字符串

// Save the original `Date` function
const OriginalDate = Date;
// Replace it with our own
Date = function Date(...args) {
    // Called via `new`?
    if (!new.target) {
        // No, just pass the call on
        return OriginalDate(...args);
    }
    // Determine what constructor to call
    const ctor = new.target === Date ? OriginalDate : new.target;
    // Called via `new`
    if (args.length !== 0) {
        // Date constructor arguments were provided, just pass through
        return Reflect.construct(ctor, args);
    }
    // It's a `new Date()` call, mock the date we want; in this
    // example, Jan 1st 2000:
};
// Make our replacement look like the original (which has `length = 7`)
// You can't assign to `length`, but you can redefine it
Object.defineProperty(Date, "length", {
    value: OriginalDate.length,
    configurable: true
});

console.log("new Date()", new Date());
console.log("new Date(2021, 7, 3)", new Date(2021, 7, 3));

mw3dktmi

mw3dktmi2#

谢谢你@t-j-crowder,这是我迄今为止找到的最好的解决方案.我对它进行了一些定制,所以Date.now也可以工作。
另外一个建议是,在脚本的开头放置断点,在控制台中运行代码并恢复执行,以获得最佳的日期一致性。
我的修改:

// Save the original `Date` function
const OriginalDate = Date;
const fakeDateArgs = [2022, 5, 3]; // beware month is 0 based
let fakeDate;
// Replace it with our own
Date = function Date(...args) {
    // Called via `new`?
    if (!new.target) {
        // No, just pass the call on
        return OriginalDate(...args);
    }
    // Determine what constructor to call
    const ctor = new.target === Date ? OriginalDate : new.target;
    // Called via `new`
    if (args.length !== 0) {
        // Date constructor arguments were provided, just pass through
        return Reflect.construct(ctor, args);
    }
    // It's a `new Date()` call, mock the date we want; in this
    fakeDate = Reflect.construct(ctor, fakeDateArgs);
    return fakeDate;
};
// Make our replacement look like the original (which has `length = 7`)
// You can't assign to `length`, but you can redefine it
Object.defineProperty(Date, "length", {
    value: OriginalDate.length,
    configurable: true
});

Object.defineProperty(Date, "now", {
    value: () => fakeDate.getTime(),
    configurable: true
});

字符串

ukxgm1gy

ukxgm1gy4#

下面是在浏览器中模拟Date对象的实现。Month总是从零开始,默认日期设置为2024年1月1日,可以更改。这最好仅用于测试目的:

((originalDate) => {
    // Function to mock the Date object
    function MockDate(...args) {
        if (args.length) {
            return new originalDate(...args);
        }
        // Default date: January 1, 2024
        return new originalDate(2024, 0, 1);
    }

    MockDate.prototype = originalDate.prototype;
    MockDate.now = () => new MockDate().getTime();
    MockDate.UTC = originalDate.UTC;
    MockDate.parse = originalDate.parse;

    // Override the global Date object
    Date = MockDate;
})(Date);

字符串
可使用以下设备进行测试:

console.log(new Date());

相关问题