bun:test 允许你在测试中更改当前时间。
这适用于以下任意一种情况:
Date.now
new Date()
new Intl.DateTimeFormat().format()
目前定时器尚未受到影响,但可能会在未来的 Bun 版本中支持。
setSystemTime
要更改系统时间,请使用 setSystemTime:

test.ts
import { setSystemTime, beforeAll, test, expect } from "bun:test";
beforeAll(() => {
setSystemTime(new Date("2020-01-01T00:00:00.000Z"));
});
test("它是2020年", () => {
expect(new Date().getFullYear()).toBe(2020);
});
为了支持使用 Jest 的 useFakeTimers 和 useRealTimers 的已有测试,可以使用 useFakeTimers 和 useRealTimers:

test.ts
test("就像在 jest 中一样", () => {
jest.useFakeTimers();
jest.setSystemTime(new Date("2020-01-01T00:00:00.000Z"));
expect(new Date().getFullYear()).toBe(2020);
jest.useRealTimers();
expect(new Date().getFullYear()).toBeGreaterThan(2020);
});
test("与 jest 不同", () => {
const OriginalDate = Date;
jest.useFakeTimers();
if (typeof Bun === "undefined") {
// 在 Jest 中,Date 构造函数会改变
// 这可能导致各种错误,因为测试前后 Date !== Date。
expect(Date).not.toBe(OriginalDate);
expect(Date.now).not.toBe(OriginalDate.now);
} else {
// 在 bun:test 中,使用 useFakeTimers 时 Date 构造函数不会改变
expect(Date).toBe(OriginalDate);
expect(Date.now).toBe(OriginalDate.now);
}
});
定时器 — 注意我们尚未实现内置的定时器模拟支持,但这在计划中。
重置系统时间
要重置系统时间,请调用 setSystemTime 并不传入参数:

test.ts
import { setSystemTime, expect, test } from "bun:test";
test("曾经是2020年,只有一会儿。", () => {
// 先设置为某个时间!
setSystemTime(new Date("2020-01-01T00:00:00.000Z"));
expect(new Date().getFullYear()).toBe(2020);
// 重置它!
setSystemTime();
expect(new Date().getFullYear()).toBeGreaterThan(2020);
});
使用 jest.now() 获取模拟时间
当你使用模拟时间(通过 setSystemTime 或 useFakeTimers)时,可以使用 jest.now() 获取当前模拟的时间戳:

test.ts
import { test, expect, jest } from "bun:test";
test("获取当前模拟时间", () => {
jest.useFakeTimers();
jest.setSystemTime(new Date("2020-01-01T00:00:00.000Z"));
expect(Date.now()).toBe(1577836800000); // 2020年1月1日的时间戳
expect(jest.now()).toBe(1577836800000); // 相同的值
jest.useRealTimers();
});
当你需要直接访问模拟时间而不创建新的 Date 对象时,这非常有用。
设置时区
默认情况下,所有 bun test 运行的时区均设为 UTC (Etc/UTC),除非被覆盖。要更改时区,可以在运行 bun test 时传入 $TZ 环境变量:
TZ=America/Los_Angeles bun test
或者在运行时设置 process.env.TZ:

test.ts
import { test, expect } from "bun:test";
test("欢迎来到加利福尼亚!", () => {
process.env.TZ = "America/Los_Angeles";
expect(new Date().getTimezoneOffset()).toBe(420);
expect(new Intl.DateTimeFormat().resolvedOptions().timeZone).toBe("America/Los_Angeles");
});
test("欢迎来到纽约!", () => {
// 与 Jest 不同,你可以在运行时多次设置时区,并且可以生效。
process.env.TZ = "America/New_York";
expect(new Date().getTimezoneOffset()).toBe(240);
expect(new Intl.DateTimeFormat().resolvedOptions().timeZone).toBe("America/New_York");
});
与 Jest 不同,你可以在运行时多次设置时区,并且可以生效。