Jest · Unit tests that survive refactors
What are the pitfalls of fake timers?
Short answer
Fake timers freeze the clock and queue callbacks, so awaited promises may never settle and libraries that captured real timers break. Fake only the APIs you need, flush microtasks, and always restore.
A fake timer does not simply speed up time. It replaces the scheduling primitives. Code awaiting a promise that resolves inside a setTimeout will hang until the test advances the clock, and code that compared two timestamps may now see zero elapsed time.
test("loads after the retry delay", async () => {
jest.useFakeTimers();
const promise = loadWithRetry();
await jest.advanceTimersByTimeAsync(1000);
await expect(promise).resolves.toEqual({ ok: true });
jest.useRealTimers();
});Common failure modes
- A promise never resolves because the timeout that resolves it was queued but never advanced
- A library captured the real timer before fake timers were installed
- A recursive interval loops forever under
runAllTimers - A test leaves timers pending and Jest warns about open handles
- Ordering between microtasks and timers is misread, so assertions run too early
Prefer advanceTimersByTimeAsync when promises are involved, because it advances the clock and yields to the microtask queue. Modern Jest also supports shouldAdvanceTime, which lets fake timers advance with real time for libraries that keep their own heartbeat. Scope fakes with doNotFake when only one timer matters.
Follow-ups you should expect
Interviewers use these to check whether the first answer was understanding or memorisation.
- 1Why can a promise hang under fake timers?
- 2What does shouldAdvanceTime change?
- 3How do you avoid a recursive interval looping forever?
- 4When should you avoid fake timers entirely?
Say it in the interview
Fake timers replace the scheduler, not just the delay, so promise callbacks queued on a timer do not run until I advance the clock. I use advanceTimersByTimeAsync when async code is involved, and I fake only the specific APIs I need. Libraries that captured real timers can break, so I check their docs or scope the fake. Most importantly, I restore real timers so nothing leaks.
Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.
Related questions
Reading is step one
Now say it out loud.
Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live Jest mock interview and get scored feedback on depth, clarity and confidence.