スポンサーリンク

Angularコンポーネントのユニットテストの書き方(Vitest対応)

この記事は「Angular × Vite ユニットテスト入門|Vitestで始めるテスト完全ガイド」シリーズの一部です。

Angularコンポーネントのユニットテストの書き方(Vitest対応)

Angularのユニットテストは「難しそう」と感じがちですが、基本パターンはシンプルです。本記事では、Angularのコンポーネントテストを、Vitest環境で最小構成に絞って解説します。

テスト対象のコンポーネントとセットで、コードの意味を理解しながら進めていきます。

テスト対象コンポーネント

まずはシンプルなコンポーネントを用意します。

my.component.ts

import { Component, Input } from '@angular/core';

@Component({
selector: 'app-my',
standalone: true,
template: `
<h1>{{ title }}</h1>
<button (click)="changeTitle()">Change</button>
`
})
export class MyComponent {
@Input() title = '';

changeTitle() {
this.title = 'Changed!';
}
}

コンポーネントのコード解説

@Inputで値を受け取る

@Input() title = '';

親コンポーネントから値を受け取るプロパティです。
テストではこの値を直接セットして動作確認を行います。

テンプレートの役割

<h1>{{ title }}</h1>
<button (click)="changeTitle()">Change</button>
  • {{ title }}:画面に表示される値
  • (click):ボタンクリック時の処理を紐づけ

メソッドの処理

changeTitle() {
this.title = 'Changed!';
}

クリック時にタイトルを書き換えるシンプルなロジックです。

テストコード(Vitest)

my.component.spec.ts

import { describe, it, expect, beforeEach } from 'vitest';
import { TestBed } from '@angular/core/testing';
import { MyComponent } from './my-component';

describe('MyComponent', () => {
  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [MyComponent],
    }).compileComponents();
  });

  it('should render input title', () => {
    const fixture = TestBed.createComponent(MyComponent);
    const component = fixture.componentInstance;

    component.title = 'Hello';
    fixture.detectChanges();

    const el = fixture.nativeElement as HTMLElement;
    expect(el.querySelector('h1')?.textContent).toContain('Hello');
  });

  it('should change title when button clicked', () => {
    const fixture = TestBed.createComponent(MyComponent);
    const component = fixture.componentInstance;

    component.title = 'Before';
    fixture.detectChanges();

    const button = fixture.nativeElement.querySelector('button');
    button.click();
    fixture.detectChanges();

    expect(component.title).toBe('Changed!');
  });
});

テストコードの解説

describeでテストをまとめる

describe('MyComponent', () => {

テストのグループを定義します。
コンポーネント単位でまとめるのが基本です。

TestBedでテスト環境を構築

await TestBed.configureTestingModule({
imports: [MyComponent],
}).compileComponents();
  • Angular専用のテスト環境を構築
  • Standaloneコンポーネントはimportsに指定するだけでOK

コンポーネントの生成

const fixture = TestBed.createComponent(MyComponent);
const component = fixture.componentInstance;
  • fixture:テスト用のラッパー(DOM含む)
  • component:クラス本体

detectChangesの役割

fixture.detectChanges();

Angularの変更検知を実行します。
これを呼ばないと、テンプレートに値が反映されません。

DOMの検証

const el = fixture.nativeElement as HTMLElement;
expect(el.querySelector('h1')?.textContent).toContain('Hello');

実際の画面に表示される内容を検証します。
ユーザー視点のテストになります。

クリックイベントのテスト

const button = fixture.nativeElement.querySelector('button');
button.click();
fixture.detectChanges();
  • ボタンを取得
  • clickイベントを実行
  • 変更検知で反映
expect(component.title).toBe('Changed!');

クリック後の状態を確認します。

最低限覚えるべき流れ

Angularコンポーネントのテストは、次の流れを覚えるだけで十分です。

  1. TestBedで準備
  2. createComponentで生成
  3. 値をセット
  4. detectChangesで反映
  5. DOMまたは状態を検証

まとめ

本記事では、Angularコンポーネントのユニットテストを最小構成で解説しました。

  • @Inputのテスト方法
  • DOMの確認方法
  • クリックイベントの検証
  • detectChangesの重要性

まずはこの基本形を理解することで、Angularのテストに対するハードルは大きく下がります。
次は「サービスを使ったコンポーネントのテスト」や「非同期処理のテスト」に進むと、さらに実務レベルに近づきます。