Skip to content

test: use Bun's fake timers to speed up unit tests #29

@koistya

Description

@koistya

Background

Bun v1.3.4 introduced fake timers for bun:test, enabling time manipulation without real delays. This is a great opportunity to speed up our unit tests.

Current state

Our unit tests use manual setTimeout mocking to test timeout behavior. For example, in test/unit/disposable/timeout.test.ts:

const setTimeoutSpy = spyOn(globalThis, "setTimeout")
  .mockImplementation((callback: any, delay: any) => {
    timeoutCallback = callback;
    capturedDelay = delay;
    return 0;
  });

// Later, manually invoke the callback
timeoutCallback();

This works but requires boilerplate and manual callback invocation. Bun's fake timers provide a cleaner API.

Proposal

Refactor unit tests to use Bun's fake timers:

import { jest } from "bun:test";

test("disposal timeout", () => {
  jest.useFakeTimers();
  
  // ... set up test ...
  
  // Advance time instead of manual callback
  jest.advanceTimersByTime(100);
  
  // Assertions...
  
  jest.useRealTimers();
});

Scope

In scope (unit tests only):

  • test/unit/disposable/timeout.test.ts — Primary candidate, already mocks setTimeout
  • test/unit/disposable/concurrent.test.ts — Uses Bun.sleep() for timing

Out of scope:

  • Integration/contract/e2e tests — These test real backend behavior where actual time delays are necessary

Implementation notes

  • Bun's fake timers are Jest-compatible: jest.useFakeTimers(), jest.advanceTimersByTime(), jest.useRealTimers()
  • Always call useRealTimers() in cleanup to avoid test pollution
  • Check Bun docs for full API
  • Requires Bun ≥1.3.4 (update @types/bun if needed)

Getting started

  1. Read the Bun fake timers docs
  2. Start with test/unit/disposable/timeout.test.ts
  3. Run bun run test:unit to verify changes
  4. Open a PR with the refactored tests

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions