🦁

[PHP]名前付き引数を使用して、ユニットテストで楽をする

2024/06/01に公開

サンプルコード

class HogeClass {
  public function __construct(
    public readonly Aクラス $Aクラス,
    public readonly Bクラス $Bクラス,
    public readonly Cクラス $Cクラス,
    public readonly Dクラス $Dクラス
  ) {}
}

このようなHogeClassのテストを書く時に、次のようなケースがあります。

  • AD間の結合テスト
  • ABC間の結合テスト

そして、部分的にモックを使ったり、使わないクラス依存クラスをモック化する選択肢があります。

モックを利用した場合のデメリット

しかしモック化した場合のデメリットとして、以下の点が挙げられます。

  • 実際の依存クラスの変更に気づかない可能性がある
  • モックのメソッドが実際のメソッドと一致しない場合がある
  • 実装の変更がテストに反映されないことがある

名前付き引数を使用して、実際のクラスを利用してテストクラスを作成する

テスト用のヘルパー関数と名前付き引数を組み合わせることで、
実際のクラスを使って依存クラスを楽に差し替えることができます。

サンプルコード

function testHogeClass生成(
  Aクラス $a = new Aクラス(),
  Bクラス $b = new Bクラス(),
  Cクラス $c = new Cクラス(),
  Dクラス $d = new Dクラス()
) {
  return new HogeClass(
    $a,
    $b,
    $c,
    $d
  );
}

例えば、C,Dクラスのテストを書く場合は次のように名前付き引数で依存クラスを代入します。名前付き引数を使うことで、A,Bクラスはすでに宣言されたデフォルト値を使用するため、省略することが出来ます。

$testHoge = testHogeClass生成(
  Cクラス: new MockCクラス(),
  Dクラス: new MockDクラス()
);

同様に、A,Dクラスのテストを書く場合も名前付き引数を使用して、B、Cクラスを省略することができます。

$testHoge = testHogeClass生成(
  Aクラス: new MockAクラス(),
  Dクラス: new MockDクラス()
);

メリット

このようにした場合、以下のメリットが生まれます。

  • 実際のクラスを利用してテストケースを作成しているため、コンストラクタやメソッドの変更に気づける
  • ヘルパー関数を一度作れば再利用が容易になる

まとめ

名前付き引数を活用することで、依存クラスの変更にも柔軟に対応でき、
より堅牢なテストケースを作成することが可能です。
ユニットテストの品質を向上させるために、名前付き引数の導入を検討してみてはいかがでしょうか。

Discussion