サーバーサイドエンジニアの鈴木です。
PHPUnit では期待する例外が発生することをテストするために、@expectedException
アノテーションが用意されています。このアノテーションに例外クラス名を指定することで、そのテストが実行されたときに指定した例外クラスのインスタンスがスローされるかどうかテストをすることができます。
しかしながら、 同じ例外クラス (例えば、Exception クラス等)のインスタンスがそのままスローされているメソッドが複数含まれている場合、@expectedException
アノテーションだけではどの例外が発生するのか識別することができません。
具体例を用いてご説明します。
例えば、下記のような 1 つのメソッドの中に 2 箇所で同じ例外クラスの例外が発生させるメソッドがあったとします。この場合、Exception
クラスのインスタンスがスローされることはテストすることができますが、どちらの例外が発生したのか判別することができません。
<?php class Sample { public function helloWorld($a, $b) { if (!$a) { throw new Exception('$a is invalid'); } if (!$b) { throw new Exception('$b is invalid'); } return 'Hello World'; } }
その場合の解決方法の 1 つとして、@expectedExceptionMessage
@expectedExceptionMessageRegExp
@expectedExceptionCode
といったアノテーションを使用するという方法があります。
これらのアノテーションの動作は下記の通りです。
- @expectedExceptionMessage : 期待する例外メッセージをテストする
- @expectedExceptionMessageRegExp : 期待する例外メッセージを正規表現を使用してテストする
- @expectedExceptionCode : 期待する例外コードをテストする
@expectedExceptionMessage
アノテーションを使用して 2 つの例外をテストする場合は下記のようなコードになります。
<?php require 'Sample.php'; class SampleTest extends PHPUnit_Framework_TestCase { /** * @expectedException Exception * @expectedExceptionMessage $a is invalid */ public function testHelloWorldThrowsExpectedExceptionMessageWhenAIsNull() { $sample = new Sample(); $sample->helloWorld(null, 'test'); } /** * @expectedException Exception * @expectedExceptionMessage $b is invalid */ public function testHelloWorldThrowsExpectedExceptionMessageWhenBIsNull() { $sample = new Sample(); $sample->helloWorld('test', null); } }
@expectedExceptionCode
アノテーションを使う場合は、Exception
クラスのコンストラクタの第 2 引数に任意の例外コードを渡すように修正することが必要になりますが、それ以外は @expectedExceptionMessage
アノテーションと同じように使うことができます。
この方法では既存のメソッドの挙動を変えずに(またはほとんど変えることなく)例外が発生するケースをテストでカバーすることができますので、そういった場面に出くわしたらぜひお試しください。
公式ドキュメント
@expectedExceptionMessage https://phpunit.de/manual/current/ja/appendixes.annotations.html#appendixes.annotations.expectedExceptionMessage
@expectedExceptionMessageRegExp https://phpunit.de/manual/current/ja/appendixes.annotations.html#appendixes.annotations.expectedExceptionMessageRegExp
@expectedExceptionCode https://phpunit.de/manual/current/ja/appendixes.annotations.html#appendixes.annotations.expectedExceptionCode
積極採用中!!
子育て家族アプリFamm、カップル専用アプリPairyを運営するTimers inc. では、現在エンジニアを積極採用中! 急成長中のサービスの技術の話を少しでも聞いてみたい方、スタートアップで働きたい方など、是非お気軽にご連絡ください! 採用HP : http://timers-inc.com/engineerings