74. Unit Testing Components (Shallow Testing)
When unit testing a component, we focus only on its logic and its template interaction, ignoring its child components to keep the test focused (Shallow Testing).
Testing Component Logic
We interact directly with the component instance.
typescript it('should correctly calculate total price', () => { component.price = 100; component.taxRate = 0.1; // Testing a class method expect(component.calculateTotal()).toBe(110); });
Testing Template Interaction (The DOM)
We use the fixture object to query the DOM and trigger change detection.
fixture.detectChanges(): Forces Angular to run change detection and update the DOM based on current component state.fixture.nativeElement: The raw DOM element of the component's host.DebugElement: Angular's wrapper for the DOM element, used for querying and dispatching events.
typescript it('should render title in an H1 tag', () => { component.title = 'Test App'; // 1. Trigger change detection to render the title fixture.detectChanges();
// 2. Query the DOM const compiled = fixture.nativeElement as HTMLElement; const h1 = compiled.querySelector('h1');
// 3. Assert the result expect(h1?.textContent).toContain('Test App'); });
it('should call increment() on button click', () => { spyOn(component, 'increment'); // Spy on the method fixture.detectChanges();
const button = fixture.debugElement.query(By.css('button')); button.triggerEventHandler('click', null); // Simulate a click
expect(component.increment).toHaveBeenCalled(); });
Shallow testing ensures your test breaks only if the component you're currently testing changes, not if a distant child component changes.