Component testing helps you check if parts of your app work right by themselves. It finds mistakes early and keeps your app strong.
Component testing basics in Angular
Start learning this pattern below
Jump into concepts and practice - no test required
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MyComponent } from './my.component'; describe('MyComponent', () => { let component: MyComponent; let fixture: ComponentFixture<MyComponent>; beforeEach(() => { TestBed.configureTestingModule({ declarations: [MyComponent] }).compileComponents(); fixture = TestBed.createComponent(MyComponent); component = fixture.componentInstance; fixture.detectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); });
Use TestBed to set up the testing environment for your component.
fixture.detectChanges() runs Angular's change detection to update the view.
title property equals 'Hello'.it('should have title as Hello', () => { expect(component.title).toBe('Hello'); });
<h1> tag.it('should render title in h1 tag', () => { const compiled = fixture.nativeElement as HTMLElement; expect(compiled.querySelector('h1')?.textContent).toContain('Hello'); });
This example shows a simple Angular component with a greeting message. The test checks if the component is created, if the greeting property has the right text, and if the text appears in the HTML inside an <h1> tag.
import { Component } from '@angular/core'; @Component({ selector: 'app-greeting', template: `<h1>{{ greeting }}</h1>` }) export class GreetingComponent { greeting = 'Hello, Angular!'; } // Test file: greeting.component.spec.ts import { ComponentFixture, TestBed } from '@angular/core/testing'; import { GreetingComponent } from './greeting.component'; describe('GreetingComponent', () => { let component: GreetingComponent; let fixture: ComponentFixture<GreetingComponent>; beforeEach(() => { TestBed.configureTestingModule({ declarations: [GreetingComponent] }).compileComponents(); fixture = TestBed.createComponent(GreetingComponent); component = fixture.componentInstance; fixture.detectChanges(); }); it('should create the component', () => { expect(component).toBeTruthy(); }); it('should have greeting text', () => { expect(component.greeting).toBe('Hello, Angular!'); }); it('should render greeting in h1 tag', () => { const compiled = fixture.nativeElement as HTMLElement; expect(compiled.querySelector('h1')?.textContent).toContain('Hello, Angular!'); }); });
Always import ComponentFixture and TestBed from @angular/core/testing.
Use fixture.nativeElement to access the rendered HTML for checking content.
Run fixture.detectChanges() after changing component properties to update the view.
Component testing checks if parts of your app work alone.
Use TestBed to set up and create components for testing.
Check both component properties and rendered HTML to ensure correct behavior.
Practice
Solution
Step 1: Understand component testing scope
Component testing focuses on testing a single component in isolation, not the whole app or services alone.Step 2: Compare options with definition
Only To check if a component works correctly by itself describes testing a component by itself, which matches the purpose of component testing.Final Answer:
To check if a component works correctly by itself -> Option BQuick Check:
Component testing = isolated component check [OK]
- Confusing component testing with full app testing
- Thinking services are tested alone in component tests
- Assuming database is tested in component tests
Solution
Step 1: Identify Angular testing utilities
TestBed is the Angular utility designed to configure and create components in tests.Step 2: Eliminate unrelated options
HttpClient is for HTTP requests, NgModule defines modules, RouterModule handles routing, none create test components.Final Answer:
TestBed -> Option AQuick Check:
TestBed sets up test components [OK]
- Confusing TestBed with NgModule
- Choosing HttpClient which is unrelated to testing setup
- Selecting RouterModule which is for routing
fixture.nativeElement.textContent contain?TestBed.configureTestingModule({ declarations: [HelloComponent] }).compileComponents();
const fixture = TestBed.createComponent(HelloComponent);
fixture.componentInstance.name = 'Alice';
fixture.detectChanges();
@Component({ selector: 'app-hello', template: '<p>Hello, {{name}}!</p>' })
class HelloComponent { name = ''; }Solution
Step 1: Understand component property binding
The component'snameproperty is set to 'Alice' before change detection.Step 2: Effect of
This updates the template to reflect the newfixture.detectChanges()namevalue, so the paragraph shows 'Hello, Alice!'.Final Answer:
Hello, Alice! -> Option AQuick Check:
Property set + detectChanges updates template [OK]
- Forgetting to call detectChanges so template stays old
- Assuming template shows variable name literally
- Thinking missing name causes error
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [MyComponent]
});
fixture = TestBed.createComponent(MyComponent);
component = fixture.componentInstance;
});Solution
Step 1: Check TestBed setup sequence
When using TestBed with components,compileComponents()must be called to compile templates before creating the component.Step 2: Identify missing step
The code configures the module but skipscompileComponents(), which can cause errors or incomplete setup.Final Answer:
Missing call to compileComponents() before createComponent() -> Option CQuick Check:
compileComponents() needed before createComponent() [OK]
- Skipping compileComponents() causes template errors
- Declaring variables inside beforeEach unnecessarily
- Thinking createComponent() is optional
@Component({ template: '<ul><li *ngFor="let item of items">{{item}}</li></ul>' })
class ListComponent { @Input() items: string[] = []; }Solution
Step 1: Set input and update template
Assign the input array tocomponent.itemsand calldetectChanges()to update the rendered list.Step 2: Verify rendered list length
Check the number of<li>elements in the DOM matches the input array length usingquerySelectorAll('li').length.Final Answer:
Set component.items, call detectChanges(), then check li elements count -> Option DQuick Check:
Input set + detectChanges + DOM check = correct test [OK]
- Not calling detectChanges() after input change
- Checking component property only without DOM verification
- Calling detectChanges() before setting inputs
