Interview question
Test a signal component in production-like zoneless mode
Tests input replacement, DOM events, computed rendering, and stable identity without forcing change detection around missing notifications.
TL;DR
Tests input replacement, DOM events, computed rendering, and stable identity without forcing change detection around missing notifications.
Angular TestBed, zoneless change detection, input signals, DOM events, whenStable, computed state, and stable rendering.
Practice the problem like a real interview: restate, reason, implement, and test.
Test the signal-driven product list with zoneless change detection. Set its required input through Angular, type into the real search field, select a row, replace the parent input, and verify the DOM after whenStable. Do not add repeated detectChanges calls to make plain-field mutations visible.
set products -> all rows render
dispatch input "mo" -> filtered rows render after stability
click Mouse -> aria-pressed true
replace products without Mouse -> no stale selected row
componentRef.setInput for the required input.fixture.whenStable() after Angular notifications.provideZonelessChangeDetection.import {provideZonelessChangeDetection} from '@angular/core';
import {TestBed} from '@angular/core/testing';
it('filters and reconciles selection in zoneless mode', async () => {
TestBed.configureTestingModule({
imports: [ProductList],
providers: [provideZonelessChangeDetection()],
});
const fixture = TestBed.createComponent(ProductList);
fixture.componentRef.setInput('products', [
{id: 'k', name: 'Keyboard'},
{id: 'm', name: 'Mouse'},
{id: 'd', name: 'Monitor'},
]);
await fixture.whenStable();
const input: HTMLInputElement = fixture.nativeElement.querySelector('input');
input.value = 'mo';
input.dispatchEvent(new Event('input'));
await fixture.whenStable();
const mouse = [...fixture.nativeElement.querySelectorAll('button')]
.find((button: HTMLButtonElement) => button.textContent?.includes('Mouse'))!;
mouse.click();
await fixture.whenStable();
expect(mouse.getAttribute('aria-pressed')).toBe('true');
fixture.componentRef.setInput('products', [{id: 'd', name: 'Monitor'}]);
await fixture.whenStable();
expect(fixture.componentInstance.selectedProduct()).toBeNull();
});
The test creates one fixture and performs O(n) DOM queries over a small controlled list.
input.value without dispatching an input event does not notify Angular.Next in Angular Practical Labs: Deferred chart states