執行環境套件管理器打包器測試執行器程式碼檢查格式化指南參考部落格意見回饋

日期和時間

學習如何在你的 Bun 測試中使用 setSystemTime 和 Jest 相容函式操作時間和日期

bun:test 允許你在測試中更改當前時間。

這適用於以下任意一種情況:

  • Date.now
  • new Date()
  • new Intl.DateTimeFormat().format()。

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);
});

bun:test 也支援 Jest 的 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) 時區執行。要更改時區,可以將 TZ 環境變數傳遞給 bun test:

terminal
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("2020-07-01T00:00:00.000Z").getTimezoneOffset()).toBe(420);
  expect(new Intl.DateTimeFormat().resolvedOptions().timeZone).toBe("America/Los_Angeles");
});

test("歡迎來到紐約!", () => {
  // 與 Jest 不同,你可以在執行環境多次設定時區,並且可以生效。
  process.env.TZ = "America/New_York";
  expect(new Date("2020-07-01T00:00:00.000Z").getTimezoneOffset()).toBe(240);
  expect(new Intl.DateTimeFormat().resolvedOptions().timeZone).toBe("America/New_York");
});