Mock Date when run unit test cases with jest to make tests of Date easier.
npx @tessl/cli install tessl/npm-jest-date-mock@1.0.0Jest Date Mock is a Jest testing utility that enables developers to mock the Date class for consistent and predictable unit tests. It provides simple controls to advance, set, or reset mocked time, supporting both browser and Node.js environments with automatic environment detection.
npm install --save-dev jest-date-mockimport { advanceBy, advanceTo, clear } from "jest-date-mock";For CommonJS:
const { advanceBy, advanceTo, clear } = require("jest-date-mock");import { advanceBy, advanceTo, clear } from "jest-date-mock";
describe("Date mocking tests", () => {
beforeEach(() => {
// Set a fixed date for consistent testing
advanceTo(new Date("2023-01-01T00:00:00.000Z"));
});
afterEach(() => {
// Reset to real time after each test
clear();
});
test("should mock Date constructor", () => {
const now = new Date();
expect(now.toISOString()).toBe("2023-01-01T00:00:00.000Z");
});
test("should advance time", () => {
advanceBy(1000); // Advance by 1 second
const now = new Date();
expect(now.toISOString()).toBe("2023-01-01T00:00:01.000Z");
});
});Jest Date Mock uses a sophisticated approach to provide seamless Date mocking across different JavaScript environments:
Environment Detection: The package automatically detects the runtime environment on import and applies the appropriate mocking strategy:
global.Date with the mocked implementationglobal.window.Date with the mocked implementationDate Class Replacement: The core mocking mechanism creates a new Date class that inherits from the original Date class while intercepting constructor calls and static methods. This ensures full API compatibility while enabling time control.
State Management: Internal state tracks the current mocked timestamp, with three states:
Prototype Chain Preservation: The mocked Date class maintains the complete prototype chain and constructor relationships, ensuring instanceof checks and method availability work correctly.
Add to your package.json:
{
"jest": {
"setupFiles": ["jest-date-mock"]
}
}Or if you already have setupFiles:
{
"jest": {
"setupFiles": ["./__setups__/other.js", "jest-date-mock"]
}
}Advances the current mocked date by specified milliseconds.
/**
* Advances the current mocked date by specified milliseconds
* @param {number} ms - Milliseconds to advance the date by (defaults to 0 if falsy)
* @returns {number} The new timestamp after advancing
*/
function advanceBy(ms?: number): number;Usage:
import { advanceBy } from "jest-date-mock";
// Start from current time if no mock is active
advanceBy(5000); // Advance by 5 seconds
// Or advance from existing mock time
advanceTo(new Date("2023-01-01T00:00:00.000Z"));
advanceBy(60000); // Now at 2023-01-01T00:01:00.000ZSets the mocked date to a specific timestamp.
/**
* Sets the mocked date to a specific timestamp
* @param {number|Date|string} ms - Timestamp, Date object, or date string to set mock to; if falsy, sets to epoch (0)
* @returns {number} The timestamp that was set
*/
function advanceTo(ms?: number | Date | string): number;Usage:
import { advanceTo } from "jest-date-mock";
// Set to specific date
advanceTo(new Date("2023-06-15T12:30:00.000Z"));
// Set to timestamp
advanceTo(1687094200000);
// Set to epoch (if falsy value provided)
advanceTo(0);
advanceTo(null);
advanceTo(undefined);Clears the date mock, returning to real-time Date behavior.
/**
* Clears the date mock, returning to real-time Date behavior
* @returns {undefined}
*/
function clear(): undefined;Usage:
import { clear } from "jest-date-mock";
// After setting up mocks
advanceTo(new Date("2023-01-01"));
// Clear the mock to return to real time
clear();
// Now Date will return actual current time
const realNow = new Date();Package version string constant.
const version: string;/**
* The Date constructor interface
*/
interface DateConstructor {
new (): Date;
new (value: number | string): Date;
new (year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): Date;
(): string;
readonly prototype: Date;
now(): number;
parse(s: string): number;
UTC(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): number;
}jest-date-mock automatically detects the runtime environment and applies the appropriate mocking:
global.Dateglobal.window.DateThe package works seamlessly in both environments without any additional configuration.
When active, the mocked Date class provides:
new Date() returns the mocked timeDate.now() returns the mocked timestampDate.__OriginalDate__ provides access to the original Date classDate.current() returns the actual current time regardless of mock stateWhen jest-date-mock is active, the global Date class is enhanced with additional methods:
/**
* Returns the mocked timestamp, or real time if no mock is active
* @returns {number} Current timestamp in milliseconds
*/
Date.now(): number;
/**
* Reference to the original, unmocked Date class
* @type {DateConstructor}
*/
Date.__OriginalDate__: DateConstructor;
/**
* Returns the actual current system time, ignoring any active mock
* @returns {number} Real system timestamp in milliseconds
*/
Date.current(): number;import { advanceTo, clear } from "jest-date-mock";
describe("Time-dependent functionality", () => {
beforeEach(() => {
// Set consistent starting point
advanceTo(new Date("2023-01-01T00:00:00.000Z"));
});
afterEach(() => {
// Clean up after each test
clear();
});
// Your tests here
});import { advanceBy, advanceTo } from "jest-date-mock";
test("should handle time progression", () => {
advanceTo(new Date("2023-01-01T00:00:00.000Z"));
const start = new Date();
advanceBy(60000); // Advance 1 minute
const end = new Date();
expect(end.getTime() - start.getTime()).toBe(60000);
});