Angular 2 ユニットテスト:RouterLink とコンポーネントのテストを徹底解説! TypeScript と angular2-routing を駆使した実践ガイド
Angular 2 ユニットテストにおけるコンポーネントと RouterLink の詳細解説
Angular 2 において、コンポーネントと RouterLink を用いた単体テストは、アプリケーションのルーティング機能を検証する上で欠かせません。本記事では、このテストシナリオを深く理解するために必要な知識と実践的な手順を、TypeScript と angular2-routing を交えながら分かりやすく解説します。
テスト対象となるコンポーネント構造
まず、テスト対象となるコンポーネントの構造について理解しましょう。例として、シンプルな AppComponent
を以下に示します。
<a [routerLink]="'/products'">商品一覧へ</a>
このテンプレートには、/products
パスへのルーティングリンクが含まれています。単体テストでは、このリンクをクリックした際に適切なコンポーネントがレンダリングされることを検証します。
テストに必要なモジュールと設定
テストを実行するには、以下のモジュールを TestBed
にインポートする必要があります。
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';
import { ProductsComponent } from './products.component'; // ルーティング先のコンポーネント
上記のモジュールに加え、テスト対象となるコンポーネントとルーティング設定を含むモジュールもインポートする必要があります。
RouterLink のテスト手順
RouterLink のテストは、以下の手順で実行できます。
- コンポーネントFixture を作成
TestBed.createComponent
を使用して、テスト対象となるコンポーネントのインスタンスとComponentFixture
を取得します。 - リンク要素を取得
fixture.debugElement.query(By.css('a'))
のようなセレクターを用いて、テンプレート内の RouterLink 要素を取得します。 - リンクをクリックシミュレート
triggerEventHandler
メソッドを使用して、取得したリンク要素に対してクリックイベントをシミュレートします。 - ナビゲーションを確認
router.navigateByUrl
メソッドが呼び出されたことを確認します。このメソッドは、テスト対象コンポーネントが適切なコンポーネントにルーティングされたことを示します。
実装例
以下のコードは、上記のテスト手順を実装した例です。
let fixture: ComponentFixture<AppComponent>;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule.withRoutes([{ path: '/products', component: ProductsComponent }])],
declarations: [AppComponent],
});
fixture = TestBed.createComponent(AppComponent);
});
it('should navigate to products component on link click', () => {
const routerLink = fixture.debugElement.query(By.css('a'));
routerLink.triggerEventHandler('click');
expect(router.url).toBe('/products');
});
この例では、router.url
プロパティを使用して、現在のURLが /products
であることを確認しています。
上記の例に加え、以下の点についてもテストが可能です。
- コンポーネントの状態: ルーティングされた後のコンポーネントの状態が期待通りであることを確認できます。
- ルーターイベントの発行:
router.events
プロパティを使用して、ルーティングイベントが適切に発行されていることを確認できます。
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';
import { ProductsComponent } from './products.component'; // ルーティング先のコンポーネント
describe('AppComponent', () => {
let fixture: ComponentFixture<AppComponent>;
let router: any; // Router インスタンス
beforeEach(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule.withRoutes([{ path: '/products', component: ProductsComponent }])],
declarations: [AppComponent],
});
fixture = TestBed.createComponent(AppComponent);
router = fixture.debugElement.injector.get(Router); // Router インスタンスを取得
});
it('should navigate to products component on link click', () => {
const routerLink = fixture.debugElement.query(By.css('a'));
routerLink.triggerEventHandler('click');
// router.navigateByUrl を使用してナビゲーションを確認する方法
// expect(router.url).toBe('/products');
// router.events を使用してルーティングイベントを確認する方法
router.events.subscribe((event) => {
if (event instanceof NavigationEnd) {
expect(event.urlAfterRedirects).toBe('/products');
}
});
});
// その他のテストケースを追加
});
ポイント
- テストケースを複数追加することで、より包括的なテストを行うことができます。
router.events
を使用して、ルーティングイベントが発行されていることを確認する代替方法を追加しています。
Angular 2 ユニットテストにおける RouterLink のテスト方法:代替アプローチ
Location サービスを利用する
Location
サービスは、現在のURLとブラウザ履歴を管理する機能を提供します。このサービスを利用することで、RouterLink のテストは以下の手順で行うことができます。
TestBed.inject
を使用してLocation
サービスを取得します。- リンクをクリックシミュレートします。
Location.path()
メソッドを使用して、現在のURLが期待通りであることを確認します。
例
import { Location } from '@angular/common';
it('should navigate to products component on link click', () => {
const routerLink = fixture.debugElement.query(By.css('a'));
routerLink.triggerEventHandler('click');
const location = TestBed.inject(Location);
expect(location.path()).toBe('/products');
});
RouterTestingModule の SpyRouterを利用する
RouterTestingModule
には、テスト用にモックされた Router インスタンスを提供する SpyRouter
クラスが含まれています。このクラスを利用することで、RouterLink のテストは以下の手順で行うことができます。
TestBed.inject
を使用してSpyRouter
インスタンスを取得します。SpyRouter.navigateByUrl
メソッドが呼び出されたことを確認します。
import { SpyRouter } from '@angular/router/testing';
it('should navigate to products component on link click', () => {
const routerLink = fixture.debugElement.query(By.css('a'));
routerLink.triggerEventHandler('click');
const spyRouter = TestBed.inject(SpyRouter);
expect(spyRouter.navigateByUrl).toHaveBeenCalledWith('/products');
});
それぞれの方法の利点と欠点
- SpyRouterを利用する方法
- 利点:
RouterLink
自体の動作を検証できる - 欠点:
SpyRouter
の設定が複雑
- 利点:
- Location サービスを利用する方法
- 利点: シンプルでわかりやすい
どの方法が最適かは、テストの目的や対象コンポーネントの複雑さによって異なります。状況に応じて使い分けることをおすすめします。
angular typescript angular2-routing