# Fake Timers — Jest, Vitest & Testing Library

Source: https://www.skillbyai.com/en/javascript-testing/a-timers

> Test debounce, polling and timeouts without waiting.

## Advance time instead of sleeping

Code using `setTimeout`, `setInterval` or `Date` is slow and flaky to test with real time. **Fake timers** replace these globals with a controllable clock: `jest.useFakeTimers()` / `vi.useFakeTimers()` turn them on, `advanceTimersByTime(ms)` moves the clock forward and fires due callbacks, `runAllTimers()` flushes everything (careful with intervals that reschedule forever) and `runOnlyPendingTimers()` fires only what is currently queued. When timer callbacks themselves await promises, use the async variants such as `advanceTimersByTimeAsync`. Always switch back with `useRealTimers()` in `afterEach`, so later tests are not affected.

## Testing a debounce

Vitest shown; Jest uses jest.* with the same method names.

```typescript
import { afterEach, beforeEach, expect, it, vi } from 'vitest';
import { debounce } from './debounce';

beforeEach(() => {
  vi.useFakeTimers();
});
afterEach(() => {
  vi.useRealTimers();
});

it('calls the function once after the quiet period', () => {
  const save = vi.fn();
  const debounced = debounce(save, 300);

  debounced('a');
  debounced('ab');
  vi.advanceTimersByTime(299);
  expect(save).not.toHaveBeenCalled();

  vi.advanceTimersByTime(1);
  expect(save).toHaveBeenCalledTimes(1);
  expect(save).toHaveBeenCalledWith('ab');
});
```

## A remote control for the clock

Fake timers are a remote with a fast-forward button: instead of waiting five minutes for the cake timer, you skip ahead and check the cake is out of the oven.

**Quiz:** What does vi.advanceTimersByTime(500) do under fake timers?

- [ ] Sets a 500 ms timeout on the test
- [ ] Sleeps the test for 500 ms of real time
- [x] Moves the fake clock 500 ms forward and runs any callbacks that became due
- [ ] Skips the next 500 tests

*Answer:* Moves the fake clock 500 ms forward and runs any callbacks that became due. Time only moves when the test says so.
