Bird
Raised Fist0
Angularframework~10 mins

Component testing basics in Angular - Step-by-Step Execution

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Concept Flow - Component testing basics
Write component code
Write test file
Setup TestBed with component
Create component instance
Run tests: check template & logic
Assert expected output or behavior
Test passes or fails
End
This flow shows how Angular component tests are written, set up, run, and checked for expected results.
Execution Sample
Angular
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { MyComponent } from './my.component';

describe('MyComponent', () => {
  let fixture: ComponentFixture<MyComponent>;
  beforeEach(() => {
    TestBed.configureTestingModule({ declarations: [MyComponent] }).compileComponents();
    fixture = TestBed.createComponent(MyComponent);
  });
  it('should display title', () => {
    fixture.componentInstance.title = 'Hello';
    fixture.detectChanges();
    const compiled = fixture.nativeElement;
    expect(compiled.querySelector('h1').textContent).toContain('Hello');
  });
});
This test creates the component, sets a title, triggers Angular change detection, and checks if the title appears in the template.
Execution Table
StepActionComponent Instance StateTemplate RenderedTest AssertionResult
1Configure TestBed with MyComponentNo instance yetNo templateN/ASetup done
2Create component instancetitle: undefinedInitial template with empty titleN/AInstance created
3Set title = 'Hello'title: 'Hello'Template not updated yetN/AProperty set
4Call fixture.detectChanges()title: 'Hello'<h1>Hello</h1> renderedN/ATemplate updated
5Query <h1> textContenttitle: 'Hello'<h1>Hello</h1>Check if contains 'Hello'Pass
6Test endstitle: 'Hello'<h1>Hello</h1>All assertions passedTest success
💡 Test ends after assertions pass or fail
Variable Tracker
VariableStartAfter Step 2After Step 3After Step 4Final
titleundefinedundefined'Hello''Hello''Hello'
Key Moments - 2 Insights
Why do we need to call fixture.detectChanges() after setting a property?
Because Angular does not automatically update the template when component properties change in tests. detectChanges() triggers Angular's change detection to update the template, as shown between steps 3 and 4 in the execution_table.
What does TestBed.createComponent() do?
It creates an instance of the component and its template for testing. This is shown in step 2 where the component instance is created but the template is not yet updated.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the value of 'title' after step 3?
Anull
Bundefined
C'Hello'
D'' (empty string)
💡 Hint
Check the 'Component Instance State' column at step 3 in the execution_table.
At which step does the template update to show the new title?
AStep 3
BStep 4
CStep 2
DStep 5
💡 Hint
Look at the 'Template Rendered' column in the execution_table to see when

Hello

appears.
If fixture.detectChanges() was not called, what would happen to the test assertion?
AIt would fail because the template is not updated
BIt would pass because the title is set
CIt would throw an error
DIt would skip the test
💡 Hint
Refer to the difference between steps 3 and 4 in the execution_table about template updates.
Concept Snapshot
Angular component testing basics:
- Use TestBed to configure and create component
- Create component instance with TestBed.createComponent
- Set component properties directly
- Call fixture.detectChanges() to update template
- Query DOM to check rendered output
- Use expect() to assert behavior
Full Transcript
This visual execution shows how Angular component testing works step-by-step. First, TestBed is configured with the component. Then the component instance is created but the template is not updated yet. When we set a property like title, the template still does not reflect it until fixture.detectChanges() is called. This triggers Angular's change detection and updates the template. Finally, the test queries the DOM to check if the title appears as expected and asserts the result. This process helps ensure the component behaves correctly in isolation.

Practice

(1/5)
1. What is the main purpose of component testing in Angular?
easy
A. To test the entire application at once
B. To check if a component works correctly by itself
C. To test only the services used by components
D. To check the database connection

Solution

  1. Step 1: Understand component testing scope

    Component testing focuses on testing a single component in isolation, not the whole app or services alone.
  2. 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.
  3. Final Answer:

    To check if a component works correctly by itself -> Option B
  4. Quick Check:

    Component testing = isolated component check [OK]
Hint: Component testing means testing one piece alone [OK]
Common Mistakes:
  • Confusing component testing with full app testing
  • Thinking services are tested alone in component tests
  • Assuming database is tested in component tests
2. Which Angular testing utility is used to configure and create a component for testing?
easy
A. TestBed
B. HttpClient
C. NgModule
D. RouterModule

Solution

  1. Step 1: Identify Angular testing utilities

    TestBed is the Angular utility designed to configure and create components in tests.
  2. Step 2: Eliminate unrelated options

    HttpClient is for HTTP requests, NgModule defines modules, RouterModule handles routing, none create test components.
  3. Final Answer:

    TestBed -> Option A
  4. Quick Check:

    TestBed sets up test components [OK]
Hint: TestBed is the test setup tool in Angular [OK]
Common Mistakes:
  • Confusing TestBed with NgModule
  • Choosing HttpClient which is unrelated to testing setup
  • Selecting RouterModule which is for routing
3. Given this test snippet, what will 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 = ''; }
medium
A. Hello, Alice!
B. Hello, !
C. Hello, name!
D. Error: name not defined

Solution

  1. Step 1: Understand component property binding

    The component's name property is set to 'Alice' before change detection.
  2. Step 2: Effect of fixture.detectChanges()

    This updates the template to reflect the new name value, so the paragraph shows 'Hello, Alice!'.
  3. Final Answer:

    Hello, Alice! -> Option A
  4. Quick Check:

    Property set + detectChanges updates template [OK]
Hint: detectChanges updates template with latest property values [OK]
Common Mistakes:
  • Forgetting to call detectChanges so template stays old
  • Assuming template shows variable name literally
  • Thinking missing name causes error
4. What is wrong with this test setup code?
beforeEach(() => {
  TestBed.configureTestingModule({
    declarations: [MyComponent]
  });
  fixture = TestBed.createComponent(MyComponent);
  component = fixture.componentInstance;
});
medium
A. fixture and component should be declared inside beforeEach
B. Should import MyComponent instead of declaring it
C. Missing call to compileComponents() before createComponent()
D. No need to call createComponent() in beforeEach

Solution

  1. Step 1: Check TestBed setup sequence

    When using TestBed with components, compileComponents() must be called to compile templates before creating the component.
  2. Step 2: Identify missing step

    The code configures the module but skips compileComponents(), which can cause errors or incomplete setup.
  3. Final Answer:

    Missing call to compileComponents() before createComponent() -> Option C
  4. Quick Check:

    compileComponents() needed before createComponent() [OK]
Hint: Always call compileComponents() before createComponent() [OK]
Common Mistakes:
  • Skipping compileComponents() causes template errors
  • Declaring variables inside beforeEach unnecessarily
  • Thinking createComponent() is optional
5. You want to test a component that shows a list of items passed as an input. Which approach correctly tests that the rendered list matches the input array?
@Component({ template: '<ul><li *ngFor="let item of items">{{item}}</li></ul>' })
class ListComponent { @Input() items: string[] = []; }
hard
A. Only check component.items property without inspecting the DOM
B. Set component.items but do not call detectChanges(), then check fixture.nativeElement.textContent
C. Call detectChanges() before setting component.items, then check component.items.length
D. Set component.items to an array, call detectChanges(), then check fixture.nativeElement.querySelectorAll('li').length

Solution

  1. Step 1: Set input and update template

    Assign the input array to component.items and call detectChanges() to update the rendered list.
  2. Step 2: Verify rendered list length

    Check the number of <li> elements in the DOM matches the input array length using querySelectorAll('li').length.
  3. Final Answer:

    Set component.items, call detectChanges(), then check li elements count -> Option D
  4. Quick Check:

    Input set + detectChanges + DOM check = correct test [OK]
Hint: Always call detectChanges() after input changes before checking DOM [OK]
Common Mistakes:
  • Not calling detectChanges() after input change
  • Checking component property only without DOM verification
  • Calling detectChanges() before setting inputs