日期
¥Dates
模拟定时器 API 还允许模拟 Date
对象。对于测试与时间相关的功能或模拟内部日历功能(例如 Date.now()
)来说,这是一个有用的功能。
¥The mock timers API also allows the mocking of the Date
object. This is a
useful feature for testing time-dependent functionality, or to simulate
internal calendar functions such as Date.now()
.
日期实现也是 MockTimers
类的一部分。请参阅它以获取方法和功能的完整列表。
¥The dates implementation is also part of the MockTimers
class. Refer to it
for a full list of methods and features.
注意:当一起模拟时,日期和定时器是依赖的。这意味着,如果你同时模拟了 Date
和 setTimeout
,则提前时间也会提前模拟日期,因为它们模拟单个内部时钟。
¥Note: Dates and timers are dependent when mocked together. This means that
if you have both the Date
and setTimeout
mocked, advancing the time will
also advance the mocked date as they simulate a single internal clock.
下面的示例展示了如何模拟 Date
对象并获取当前 Date.now()
值。
¥The example below show how to mock the Date
object and obtain the current
Date.now()
value.
import assert from 'node:assert';
import { test } from 'node:test';
test('mocks the Date object', (context) => {
// Optionally choose what to mock
context.mock.timers.enable({ apis: ['Date'] });
// If not specified, the initial date will be based on 0 in the UNIX epoch
assert.strictEqual(Date.now(), 0);
// Advance in time will also advance the date
context.mock.timers.tick(9999);
assert.strictEqual(Date.now(), 9999);
});
const assert = require('node:assert');
const { test } = require('node:test');
test('mocks the Date object', (context) => {
// Optionally choose what to mock
context.mock.timers.enable({ apis: ['Date'] });
// If not specified, the initial date will be based on 0 in the UNIX epoch
assert.strictEqual(Date.now(), 0);
// Advance in time will also advance the date
context.mock.timers.tick(9999);
assert.strictEqual(Date.now(), 9999);
});
如果没有设置初始纪元,则初始日期将以 Unix 纪元中的 0 为基础。这是 1970 年 1 月 1 日 00:00:00 UTC。你可以通过将 now
属性传递给 .enable()
方法来设置初始日期。该值将用作模拟 Date
对象的初始日期。它可以是正整数,也可以是另一个 Date 对象。
¥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.
import assert from 'node:assert';
import { test } from 'node:test';
test('mocks the Date object with initial time', (context) => {
// Optionally choose what to mock
context.mock.timers.enable({ apis: ['Date'], now: 100 });
assert.strictEqual(Date.now(), 100);
// Advance in time will also advance the date
context.mock.timers.tick(200);
assert.strictEqual(Date.now(), 300);
});
const assert = require('node:assert');
const { test } = require('node:test');
test('mocks the Date object with initial time', (context) => {
// Optionally choose what to mock
context.mock.timers.enable({ apis: ['Date'], now: 100 });
assert.strictEqual(Date.now(), 100);
// Advance in time will also advance the date
context.mock.timers.tick(200);
assert.strictEqual(Date.now(), 300);
});
你可以使用 .setTime()
方法手动将模拟日期移动到另一个时间。此方法仅接受正整数。
¥You can use the .setTime()
method to manually move the mocked date to another
time. This method only accepts a positive integer.
注意:此方法将执行新时间过去的任何模拟定时器。
¥Note: This method will execute any mocked timers that are in the past from the new time.
在下面的示例中,我们为模拟日期设置新时间。
¥In the below example we are setting a new time for the mocked date.
import assert from 'node:assert';
import { test } from 'node:test';
test('sets the time of a date object', (context) => {
// Optionally choose what to mock
context.mock.timers.enable({ apis: ['Date'], now: 100 });
assert.strictEqual(Date.now(), 100);
// Advance in time will also advance the date
context.mock.timers.setTime(1000);
context.mock.timers.tick(200);
assert.strictEqual(Date.now(), 1200);
});
const assert = require('node:assert');
const { test } = require('node:test');
test('sets the time of a date object', (context) => {
// Optionally choose what to mock
context.mock.timers.enable({ apis: ['Date'], now: 100 });
assert.strictEqual(Date.now(), 100);
// Advance in time will also advance the date
context.mock.timers.setTime(1000);
context.mock.timers.tick(200);
assert.strictEqual(Date.now(), 1200);
});
如果你有任何设置为过去运行的定时器,它将像调用 .tick()
方法一样执行。如果你想测试已经过去的时间相关功能,这非常有用。
¥If you have any timer that's set to run in the past, it will be executed as if
the .tick()
method has been called. This is useful if you want to test
time-dependent functionality that's already in the past.
import assert from 'node:assert';
import { test } from 'node:test';
test('runs timers as setTime passes ticks', (context) => {
// Optionally choose what to mock
context.mock.timers.enable({ apis: ['setTimeout', 'Date'] });
const fn = context.mock.fn();
setTimeout(fn, 1000);
context.mock.timers.setTime(800);
// Timer is not executed as the time is not yet reached
assert.strictEqual(fn.mock.callCount(), 0);
assert.strictEqual(Date.now(), 800);
context.mock.timers.setTime(1200);
// Timer is executed as the time is now reached
assert.strictEqual(fn.mock.callCount(), 1);
assert.strictEqual(Date.now(), 1200);
});
const assert = require('node:assert');
const { test } = require('node:test');
test('runs timers as setTime passes ticks', (context) => {
// Optionally choose what to mock
context.mock.timers.enable({ apis: ['setTimeout', 'Date'] });
const fn = context.mock.fn();
setTimeout(fn, 1000);
context.mock.timers.setTime(800);
// Timer is not executed as the time is not yet reached
assert.strictEqual(fn.mock.callCount(), 0);
assert.strictEqual(Date.now(), 800);
context.mock.timers.setTime(1200);
// Timer is executed as the time is now reached
assert.strictEqual(fn.mock.callCount(), 1);
assert.strictEqual(Date.now(), 1200);
});
使用 .runAll()
将执行当前队列中的所有定时器。这还将模拟日期提前到最后执行的定时器的时间,就好像时间已经过去一样。
¥Using .runAll()
will execute all timers that are currently in the queue. This
will also advance the mocked date to the time of the last timer that was
executed as if the time has passed.
import assert from 'node:assert';
import { test } from 'node:test';
test('runs timers as setTime passes ticks', (context) => {
// Optionally choose what to mock
context.mock.timers.enable({ apis: ['setTimeout', 'Date'] });
const fn = context.mock.fn();
setTimeout(fn, 1000);
setTimeout(fn, 2000);
setTimeout(fn, 3000);
context.mock.timers.runAll();
// All timers are executed as the time is now reached
assert.strictEqual(fn.mock.callCount(), 3);
assert.strictEqual(Date.now(), 3000);
});
const assert = require('node:assert');
const { test } = require('node:test');
test('runs timers as setTime passes ticks', (context) => {
// Optionally choose what to mock
context.mock.timers.enable({ apis: ['setTimeout', 'Date'] });
const fn = context.mock.fn();
setTimeout(fn, 1000);
setTimeout(fn, 2000);
setTimeout(fn, 3000);
context.mock.timers.runAll();
// All timers are executed as the time is now reached
assert.strictEqual(fn.mock.callCount(), 3);
assert.strictEqual(Date.now(), 3000);
});