Question presented to candidate:
"A component shows a toast 500 ms after a click. Explain how you would test it with fakeAsync and tick, how waitForAsync differs, and what changes in a new Angular 22 project that runs Vitest without Zone.js."
What a strong answer should cover:
fakeAsyncruns the test in a fake async zone: timers do not really wait, and the test body stays synchronous.tick(ms)advances virtual time and runs due timers;flush()drains all timers and returns the virtual ms skipped;flushMicrotasks()drains promises only.waitForAsyncruns the test in an async test zone with real time and finishes the test only when every task in the zone has completed.- Both are Zone.js features: without
zone.js/testingthey throw or reject; under Vitest they also needzone.js/plugins/vitest-patchto create the ProxyZone. - In a zoneless Angular 22 project the idiomatic replacements are
vi.useFakeTimers()+vi.advanceTimersByTime()+fixture.detectChanges(), or plainasync/awaitwithfixture.whenStable(). fakeAsyncthrows at the end if timers are still pending only when{ flush: false }is passed; by default it flushes them.
Clarifying questions expected:
- "Does the project load Zone.js, and which runner: Vitest or Karma/Jasmine?"
- "Is the delay a timer, a promise, or an HTTP call?"
Code / implementation expected: Yes β a Zone-based spec using fakeAsync/tick/flush/waitForAsync, and the zoneless equivalent with Vitest fake timers.