Skip to content

clock.tick(time) / await clock.tickAsync(time)

Tick the clock ahead time milliseconds.

Causes all timers scheduled within the affected time range to be called. time may be the number of milliseconds to advance the clock by, a human-readable string, or a Temporal.Duration object. Valid string formats are "08" for eight seconds, "01:00" for one minute and "02:34:10" for two hours, 34 minutes and ten seconds.

javascript
clock.tick(Temporal.Duration.from({ hours: 1, minutes: 30 }));

The tickAsync() will also break the event loop, allowing any scheduled promise callbacks to execute before running the timers.

js
import t from "tap";
import sinon from "sinon";

t.test("clock.tick advances time and fires timers", (t) => {
  const clock = sinon.useFakeTimers();

  let callCount = 0;

  setTimeout(() => {
    callCount++;
  }, 100);

  setTimeout(() => {
    callCount++;
  }, 200);

  // Before ticking, callbacks should not have fired
  t.equal(callCount, 0, "callbacks should not have fired yet");

  // Tick past the first timeout
  clock.tick(100);

  t.equal(callCount, 1, "first callback should have fired");

  // Tick past the second timeout
  clock.tick(100);

  t.equal(callCount, 2, "second callback should have fired");

  clock.restore();
  t.end();
});

t.test("clock.tick accepts human-readable strings", (t) => {
  const clock = sinon.useFakeTimers();

  let called = false;

  setTimeout(() => {
    called = true;
  }, 5000);

  // "00:00:05" = 5 seconds
  clock.tick("00:00:05");

  t.ok(called, "callback should have fired after 5 seconds");

  clock.restore();
  t.end();
});

t.test(
  "clock.tickAsync allows promise callbacks to execute first",
  async (t) => {
    const clock = sinon.useFakeTimers();

    let asyncCalled = false;
    let syncResult = "";

    setTimeout(() => {
      asyncCalled = true;
    }, 100);

    // tickAsync breaks the event loop, allowing promises to resolve
    await clock.tickAsync(100);

    t.ok(asyncCalled, "async callback should have fired");

    clock.restore();
    t.end();
  }
);