interface
test.default.MockTimers
interface MockTimers
Mocking timers is a technique commonly used in software testing to simulate and control the behavior of timers, such as setInterval and setTimeout, without actually waiting for the specified time intervals.
The MockTimers API also allows for mocking of the Date constructor and setImmediate/clearImmediate functions.
The MockTracker provides a top-level timers export which is a MockTimers instance.
Calls ().
- ): void;
Enables timer mocking for the specified timers.
Note: When you enable mocking for a specific timer, its associated clear function will also be implicitly mocked.
Note: Mocking
Datewill affect the behavior of the mocked timers as they use the same internal clock.Example usage without setting initial time:
import { mock } from 'node:test'; mock.timers.enable({ apis: ['setInterval', 'Date'], now: 1234 });The above example enables mocking for the
Dateconstructor,setIntervaltimer and implicitly mocks theclearIntervalfunction. Only theDateconstructor fromglobalThis,setIntervalandclearIntervalfunctions fromnode:timers,node:timers/promises, andglobalThiswill be mocked.Example usage with initial time set
import { mock } from 'node:test'; mock.timers.enable({ apis: ['Date'], now: 1000 });Example usage with initial Date object as time set
import { mock } from 'node:test'; mock.timers.enable({ apis: ['Date'], now: new Date() });Alternatively, if you call
mock.timers.enable()without any parameters:All timers (
'setInterval','clearInterval','Date','setImmediate','clearImmediate','setTimeout', and'clearTimeout') will be mocked.The
setInterval,clearInterval,setTimeout, andclearTimeoutfunctions fromnode:timers,node:timers/promises, andglobalThiswill be mocked. TheDateconstructor fromglobalThiswill be mocked.If there is no initial epoch set, the initial date will be based on 0 in the Unix epoch. This is
January 1st, 1970, 00:00:00 UTC. You can set an initial date by passing a now property to the.enable()method. This value will be used as the initial date for the mocked Date object. It can either be a positive integer, or another Date object. This function restores the default behavior of all mocks that were previously created by this
MockTimersinstance and disassociates the mocks from theMockTrackerinstance.Note: After each test completes, this function is called on the test context's
MockTracker.import { mock } from 'node:test'; mock.timers.reset();Triggers all pending mocked timers immediately. If the
Dateobject is also mocked, it will also advance theDateobject to the furthest timer's time.The example below triggers all pending timers immediately, causing them to execute without any delay.
import assert from 'node:assert'; import { test } from 'node:test'; test('runAll functions following the given order', (context) => { context.mock.timers.enable({ apis: ['setTimeout', 'Date'] }); const results = []; setTimeout(() => results.push(1), 9999); // Notice that if both timers have the same timeout, // the order of execution is guaranteed setTimeout(() => results.push(3), 8888); setTimeout(() => results.push(2), 8888); assert.deepStrictEqual(results, []); context.mock.timers.runAll(); assert.deepStrictEqual(results, [3, 2, 1]); // The Date object is also advanced to the furthest timer's time assert.strictEqual(Date.now(), 9999); });Note: The
runAll()function is specifically designed for triggering timers in the context of timer mocking. It does not have any effect on real-time system clocks or actual timers outside of the mocking environment.- milliseconds: number): void;
Sets the current Unix timestamp that will be used as reference for any mocked
Dateobjects.import assert from 'node:assert'; import { test } from 'node:test'; test('runAll functions following the given order', (context) => { const now = Date.now(); const setTime = 1000; // Date.now is not mocked assert.deepStrictEqual(Date.now(), now); context.mock.timers.enable({ apis: ['Date'] }); context.mock.timers.setTime(setTime); // Date.now is now 1000 assert.strictEqual(Date.now(), setTime); }); - tick(milliseconds: number): void;
Advances time for all mocked timers.
Note: This diverges from how
setTimeoutin Node.js behaves and accepts only positive numbers. In Node.js,setTimeoutwith negative numbers is only supported for web compatibility reasons.The following example mocks a
setTimeoutfunction and by using.tickadvances in time triggering all pending timers.import assert from 'node:assert'; import { test } from 'node:test'; test('mocks setTimeout to be executed synchronously without having to actually wait for it', (context) => { const fn = context.mock.fn(); context.mock.timers.enable({ apis: ['setTimeout'] }); setTimeout(fn, 9999); assert.strictEqual(fn.mock.callCount(), 0); // Advance in time context.mock.timers.tick(9999); assert.strictEqual(fn.mock.callCount(), 1); });Alternativelly, the
.tickfunction can be called many timesimport assert from 'node:assert'; import { test } from 'node:test'; test('mocks setTimeout to be executed synchronously without having to actually wait for it', (context) => { const fn = context.mock.fn(); context.mock.timers.enable({ apis: ['setTimeout'] }); const nineSecs = 9000; setTimeout(fn, nineSecs); const twoSeconds = 3000; context.mock.timers.tick(twoSeconds); context.mock.timers.tick(twoSeconds); context.mock.timers.tick(twoSeconds); assert.strictEqual(fn.mock.callCount(), 1); });Advancing time using
.tickwill also advance the time for anyDateobject created after the mock was enabled (ifDatewas also set to be mocked).import assert from 'node:assert'; import { test } from 'node:test'; test('mocks setTimeout to be executed synchronously without having to actually wait for it', (context) => { const fn = context.mock.fn(); context.mock.timers.enable({ apis: ['setTimeout', 'Date'] }); setTimeout(fn, 9999); assert.strictEqual(fn.mock.callCount(), 0); assert.strictEqual(Date.now(), 0); // Advance in time context.mock.timers.tick(9999); assert.strictEqual(fn.mock.callCount(), 1); assert.strictEqual(Date.now(), 9999); });