CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-sinon

JavaScript test spies, stubs and mocks for framework-agnostic unit testing.

Pending
Overview
Eval results
Files

timers.mddocs/

Fake Timers

Fake timers allow you to control time-dependent code by mocking JavaScript's timing functions and Date constructor. They're essential for testing timeouts, intervals, animations, and any code that depends on the passage of time.

Capabilities

Installing Fake Timers

Replace native timing functions with controllable fake implementations.

/**
 * Install fake timers to control time-dependent code
 * @param config - Configuration options for fake timers
 * @returns Clock object for controlling time
 */
function useFakeTimers(config?: FakeTimerConfig): SinonClock;

interface FakeTimerConfig {
  /** Starting time for the fake clock (default: 0) */
  now?: number | Date;
  
  /** Array of global functions to fake */
  toFake?: ("setTimeout" | "clearTimeout" | "setInterval" | "clearInterval" | 
           "Date" | "setImmediate" | "clearImmediate" | "nextTick" | 
           "requestAnimationFrame" | "cancelAnimationFrame" | 
           "requestIdleCallback" | "cancelIdleCallback")[];
  
  /** Whether time should advance automatically (default: false) */
  shouldAdvanceTime?: boolean;
  
  /** How much time advances per automatic tick in ms (default: 20) */
  advanceTimeDelta?: number;
  
  /** Target object to install timers on (default: global) */
  target?: object;
}

Usage Examples:

import { useFakeTimers } from "sinon";

// Basic fake timers
const clock = useFakeTimers();

// Start from specific time
const clock = useFakeTimers({ now: new Date("2023-01-01") });

// Only fake specific functions
const clock = useFakeTimers({ 
  toFake: ["setTimeout", "Date"] 
});

// Automatic time advancement
const clock = useFakeTimers({
  shouldAdvanceTime: true,
  advanceTimeDelta: 50 // 50ms per tick
});

Clock Control Methods

Methods for controlling the fake clock and advancing time.

interface SinonClock {
  /**
   * Advance the clock by specified milliseconds
   * @param milliseconds - Time to advance in milliseconds
   */
  tick(milliseconds: number): void;
  
  /**
   * Advance to the next scheduled timer
   */
  next(): void;
  
  /**
   * Run all pending timers (timeouts and intervals)
   */
  runAll(): void;
  
  /**
   * Run timers until there are no more scheduled
   */
  runToLast(): void;
  
  /**
   * Advance to the next animation frame
   */
  runToFrame(): void;
  
  /**
   * Get the current fake time in milliseconds
   * @returns Current time
   */
  now(): number;
  
  /**
   * Get Date representation of current fake time
   * @returns Current date
   */
  Date(): Date;
  
  /**
   * Restore all native timing functions
   */
  restore(): void;
}

Usage Examples:

const clock = sinon.useFakeTimers();

// Schedule some timers
setTimeout(() => console.log("timeout 1"), 100);
setTimeout(() => console.log("timeout 2"), 200);
setInterval(() => console.log("interval"), 50);

// Advance time manually
clock.tick(50); // Logs: "interval"
clock.tick(50); // Logs: "timeout 1", "interval"
clock.tick(100); // Logs: "timeout 2", "interval", "interval"

// Or run all at once
clock.runAll(); // Executes all pending timers

// Clean up
clock.restore();

Fake Timer Functions

The fake implementations of native timing functions available on the clock.

interface SinonClock {
  /** Fake setTimeout implementation */
  setTimeout: typeof setTimeout;
  
  /** Fake clearTimeout implementation */
  clearTimeout: typeof clearTimeout;
  
  /** Fake setInterval implementation */
  setInterval: typeof setInterval;
  
  /** Fake clearInterval implementation */
  clearInterval: typeof clearInterval;
  
  /** Fake setImmediate implementation (Node.js) */
  setImmediate: typeof setImmediate;
  
  /** Fake clearImmediate implementation (Node.js) */
  clearImmediate: typeof clearImmediate;
  
  /** Fake Date constructor */
  Date: DateConstructor;
  
  /** Fake requestAnimationFrame implementation */
  requestAnimationFrame: typeof requestAnimationFrame;
  
  /** Fake cancelAnimationFrame implementation */
  cancelAnimationFrame: typeof cancelAnimationFrame;
  
  /** Fake performance.now implementation */
  performance: { now(): number };
}

Testing Timeouts

Common patterns for testing setTimeout-based code.

Usage Examples:

// Function that uses timeout
function debounce(func, delay) {
  let timeoutId;
  return function(...args) {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => func.apply(this, args), delay);
  };
}

// Test the debounced function
const clock = sinon.useFakeTimers();
const spy = sinon.spy();
const debouncedSpy = debounce(spy, 100);

// Call multiple times quickly
debouncedSpy("arg1");
debouncedSpy("arg2");
debouncedSpy("arg3");

// No calls yet
console.log(spy.called); // false

// Advance past debounce delay
clock.tick(100);

// Now the function is called once with the last arguments
console.log(spy.calledOnce); // true
console.log(spy.calledWith("arg3")); // true

clock.restore();

Testing Intervals

Testing setInterval-based functionality.

Usage Examples:

// Function that uses interval
function startPolling(callback, interval = 1000) {
  return setInterval(callback, interval);
}

// Test polling behavior
const clock = sinon.useFakeTimers();
const callback = sinon.spy();

const intervalId = startPolling(callback, 500);

// Advance time to trigger interval
clock.tick(500);
console.log(callback.calledOnce); // true

clock.tick(500);
console.log(callback.calledTwice); // true

// Stop and cleanup
clearInterval(intervalId);
clock.restore();

Testing Date-dependent Code

Testing code that depends on the current date/time.

Usage Examples:

// Function that uses current date
function isBusinessDay() {
  const day = new Date().getDay();
  return day >= 1 && day <= 5; // Monday-Friday
}

// Test with specific date
const clock = sinon.useFakeTimers(new Date("2023-12-25")); // Monday

console.log(isBusinessDay()); // true (Monday is business day)

// Change to weekend
clock.tick(1000 * 60 * 60 * 24 * 5); // Advance 5 days to Saturday
console.log(isBusinessDay()); // false (Saturday is weekend)

clock.restore();

Testing Promises with Timers

Combining fake timers with Promise-based code.

Usage Examples:

// Function that returns Promise with delay
function delayedPromise(value, delay) {
  return new Promise(resolve => {
    setTimeout(() => resolve(value), delay);
  });
}

// Test Promise timing
async function testDelayedPromise() {
  const clock = sinon.useFakeTimers();
  
  const promise = delayedPromise("result", 1000);
  
  // Promise is pending
  let resolved = false;
  promise.then(value => {
    resolved = true;
    console.log(value); // "result"
  });
  
  console.log(resolved); // false
  
  // Advance time to resolve Promise
  clock.tick(1000);
  
  // Allow Promise to resolve
  await Promise.resolve();
  console.log(resolved); // true
  
  clock.restore();
}

Testing Animation Frames

Testing requestAnimationFrame-based animations.

Usage Examples:

// Animation function
function animate() {
  const start = performance.now();
  
  function frame(timestamp) {
    const elapsed = timestamp - start;
    
    if (elapsed < 1000) {
      // Continue animation
      requestAnimationFrame(frame);
    }
    
    // Update animation based on elapsed time
    updateAnimation(elapsed);
  }
  
  requestAnimationFrame(frame);
}

// Test animation
const clock = sinon.useFakeTimers();
const updateSpy = sinon.spy(window, 'updateAnimation');

animate();

// Advance through several frames
clock.runToFrame(); // First frame
clock.tick(16); // ~60fps
clock.runToFrame(); // Second frame
clock.tick(16);
clock.runToFrame(); // Third frame

console.log(updateSpy.callCount); // 3

// Jump to end of animation
clock.tick(1000);
clock.runToFrame();

clock.restore();
updateSpy.restore();

Sandbox Integration

Using fake timers with sandboxes for automatic cleanup.

Usage Examples:

// Automatic fake timer management
const sandbox = sinon.createSandbox({
  useFakeTimers: true
});

// Clock is available on sandbox
setTimeout(() => console.log("timeout"), 100);
sandbox.clock.tick(100); // Logs: "timeout"

// Automatic restoration
sandbox.restore(); // Restores timers automatically

Manual sandbox integration:

const sandbox = sinon.createSandbox();

// Install fake timers in sandbox
const clock = sandbox.useFakeTimers({ now: Date.now() });

// Use clock for testing...
clock.tick(1000);

// Restore via sandbox
sandbox.restore(); // Also restores timers

Advanced Timer Configuration

Complex timer setups and configurations.

Usage Examples:

// Custom timer configuration
const clock = useFakeTimers({
  now: Date.parse("2023-01-01"),
  toFake: ["setTimeout", "Date", "performance"],
  shouldAdvanceTime: false,
  target: window // Specific target object
});

// Multiple timer operations
setTimeout(() => console.log("timeout 1"), 100);
setTimeout(() => console.log("timeout 2"), 50);
const interval = setInterval(() => console.log("interval"), 25);

// Selective advancement
clock.next(); // Runs next timer (50ms timeout 2)
clock.next(); // Runs next timer (25ms interval)
clock.next(); // Runs next timer (75ms interval again)
clock.next(); // Runs next timer (100ms timeout 1)

clearInterval(interval);
clock.restore();

Types

interface SinonClock {
  // Time control
  tick(milliseconds: number): void;
  next(): void;
  runAll(): void;
  runToLast(): void;
  runToFrame(): void;
  
  // Current time
  now(): number;
  Date(): Date;
  
  // Fake timer functions
  setTimeout: typeof setTimeout;
  clearTimeout: typeof clearTimeout;
  setInterval: typeof setInterval;
  clearInterval: typeof clearInterval;
  setImmediate: typeof setImmediate;
  clearImmediate: typeof clearImmediate;
  Date: DateConstructor;
  requestAnimationFrame: typeof requestAnimationFrame;
  cancelAnimationFrame: typeof cancelAnimationFrame;
  performance: { now(): number };
  
  // Lifecycle
  restore(): void;
}

interface FakeTimerConfig {
  now?: number | Date;
  toFake?: string[];
  shouldAdvanceTime?: boolean;
  advanceTimeDelta?: number;
  target?: object;
}

Install with Tessl CLI

npx tessl i tessl/npm-sinon

docs

assertions.md

fakes.md

index.md

matchers.md

mocks.md

promises.md

sandbox.md

spies.md

stubs.md

timers.md

tile.json