How to Test Angular Component: Simple Guide with Example
To test an Angular component, use
TestBed to configure a testing module that declares the component, then create a component fixture to access and test its instance and rendered output. Use Jasmine's expect functions to assert component behavior and DOM changes.Syntax
Testing an Angular component involves these steps:
TestBed.configureTestingModule: Sets up a testing module with declarations and imports.TestBed.createComponent: Creates a fixture for the component to test.fixture.componentInstance: Accesses the component instance for property and method testing.fixture.detectChanges(): Runs change detection to update the template.fixture.nativeElement: Accesses the rendered DOM for UI assertions.
typescript
import { TestBed } from '@angular/core/testing'; import { MyComponent } from './my.component'; describe('MyComponent', () => { beforeEach(() => { TestBed.configureTestingModule({ declarations: [MyComponent] }).compileComponents(); }); it('should create component', () => { const fixture = TestBed.createComponent(MyComponent); const component = fixture.componentInstance; fixture.detectChanges(); expect(component).toBeTruthy(); }); });
Example
This example tests a simple Angular component that shows a title and updates it on a button click.
typescript
import { Component } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; @Component({ selector: 'app-title', template: ` <h1>{{ title }}</h1> <button (click)="changeTitle()">Change Title</button> ` }) class TitleComponent { title = 'Hello Angular'; changeTitle() { this.title = 'Title Changed'; } } describe('TitleComponent', () => { let fixture: ComponentFixture<TitleComponent>; let component: TitleComponent; beforeEach(() => { TestBed.configureTestingModule({ declarations: [TitleComponent] }).compileComponents(); fixture = TestBed.createComponent(TitleComponent); component = fixture.componentInstance; fixture.detectChanges(); }); it('should display initial title', () => { const h1: HTMLElement = fixture.nativeElement.querySelector('h1'); expect(h1.textContent).toBe('Hello Angular'); }); it('should change title on button click', () => { const button: HTMLElement = fixture.nativeElement.querySelector('button'); button.click(); fixture.detectChanges(); const h1: HTMLElement = fixture.nativeElement.querySelector('h1'); expect(h1.textContent).toBe('Title Changed'); }); });
Output
PASS should display initial title
PASS should change title on button click
Common Pitfalls
Common mistakes when testing Angular components include:
- Not calling
fixture.detectChanges()after changing component properties or triggering events, so the template does not update. - Forgetting to declare the component in
TestBed.configureTestingModule, causing errors. - Trying to test private methods or properties directly instead of testing public behavior.
- Not using
asyncorwaitForAsyncwhen testing components with asynchronous operations.
typescript
/* Wrong: Missing detectChanges() after property change */ component.title = 'New Title'; // expect will fail because template not updated const h1 = fixture.nativeElement.querySelector('h1'); expect(h1.textContent).toBe('New Title'); /* Right: Call detectChanges() to update template */ component.title = 'New Title'; fixture.detectChanges(); const h1Updated = fixture.nativeElement.querySelector('h1'); expect(h1Updated.textContent).toBe('New Title');
Quick Reference
Remember these key points when testing Angular components:
- Always configure
TestBedwith your component and needed modules. - Use
fixture.detectChanges()to apply changes to the template. - Access component logic via
fixture.componentInstance. - Access rendered HTML via
fixture.nativeElement. - Use Jasmine
expectfor assertions.
Key Takeaways
Use TestBed to set up the testing environment and declare your component.
Call fixture.detectChanges() to update the template after changes.
Test both component logic and rendered output for complete coverage.
Avoid testing private members; focus on public behavior and UI.
Remember to import necessary modules if your component depends on them.