Dev Study
← Angular コース

55. DIと差し替えやすさ — テストで効く御利益

DIの最大の御利益は「本物を偽物に差し替えられる」ことです。コンポーネントは inject(UserService) と目印を頼りに受け取るだけで、実体が何かを知りません。だからDIコンテナへの登録を変えるだけで、本番ではAPIと通信する本物、テストでは決まった値を返すフェイク、と中身を切り替えられます。

テストでは TestBed.configureTestingModule の providers に { provide: UserService, useValue: fakeUserService } と登録します。これで通信なしにコンポーネントの表示ロジックだけを検証でき、テストが速く安定します。もしコンポーネント内で new UserService() していたら、この差し替えはできません。

この視点を持つと「newせずDIで受け取る」という鉄則の理由が腹落ちします。テストに限らず、開発中だけダミーデータで動かす、環境ごとに実装を切り替える、といった応用もすべて同じ仕組みです。テスト手法の詳細は別途学ぶとして、まずは「DIは差し替えのための仕組みでもある」と押さえましょう。

サンプルコード(フレームワーク環境が必要なため表示のみ)

import { TestBed } from '@angular/core/testing';
import { UserList } from './user-list';
import { UserService } from './user.service';

// 本物の代わりに使う、決まった値を返すフェイク
const fakeUserService = {
  getUsers: () => ['テスト太郎', 'テスト花子'],
};

it('ユーザー名が表示される', () => {
  TestBed.configureTestingModule({
    imports: [UserList],
    // UserService を求められたらフェイクを渡す、と登録を差し替える
    providers: [{ provide: UserService, useValue: fakeUserService }],
  });

  const fixture = TestBed.createComponent(UserList);
  fixture.detectChanges();
  // 通信なしで、フェイクの値が表示されることを検証できる
});
サンプルコードで身につける(5本) →

学んだ概念を、素朴な例から実務寄りの例まで5つの具体例で確認します。

公式ドキュメントで詳しく ↗