javascript / expert
Snippet
Testing Signal Interoperability with fakeAsync and flush
When testing Angular Signals that depend on asynchronous sources like RxJS observables (via toSignal), 'fakeAsync' is essential. It allows you to simulate the passage of time ('tick') and ensure all internal scheduled tasks are completed ('flush') before making assertions.
snippet.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import { fakeAsync, tick, flush } from '@angular/core/testing';import { toSignal } from '@angular/core/rxjs-interop';import { of, delay } from 'rxjs';it('should capture delayed RxJS values in a signal', fakeAsync(() => {const source$ = of('success').pipe(delay(1000));const sig = toSignal(source$, { initialValue: 'loading' });expect(sig()).toBe('loading');tick(1000); // Advance virtual timeexpect(sig()).toBe('success');flush(); // Ensure all microtasks are cleared}));
angular
Breakdown
1
fakeAsync(() => { ... })
Wraps the test in a zone where timer-based async operations are synchronous.
2
tick(1000);
Simulates 1 second passing in the virtual clock, triggering the RxJS delay.
3
toSignal(source$, { initialValue: 'loading' })
Converts an observable to a signal, which requires careful timing management in tests.