Stop using fakeAsync.
Testing Observables was painful. You needed marbles, tick(), and complex async schedulers.
Signals are synchronous by default. You set a value, and the computed updates instantly (or lazily upon access). The test code reads like a story.
02. Direct Access
No subscription needed. Just call the signal function.
component.count.set(2);
TestBed.flushEffects(); // Run effect() blocks
{'}'});
03. Mocking Signals
Deep Dive: Mocking Read-Only Signals
Often you need to mock a Service that exposes a read-only Signal<T>.
Technique: Just create a writable signal and cast it!
userService.currentUser = signal(mockUser) as unknown as Signal<User>;
Now your test can control the value by calling .set() on the underlying writable signal, even though the component sees it as read-only.
04. The Senior Engineer's Take
Effect Testing
Normally, you shouldn't granularly test effect() logic as it's implementation detail. Focus on testing the Computed results.
If you must test an effect (e.g. it writes to localStorage), you must call TestBed.flushEffects() because effects schedule asynchronously.