概要
前回の記事で、PHPUnitのパラメタライズドテストについて記載しました。
今回はPHPUnitで例外のテストを行う方法を記載します。
対応
まずはテスト用に下記のプログラムを用意しました。
ただパラメータが1か判定するプログラムですね。
class Example
{
public function checkNumberOwn(int $number):bool
{
if ($number !== 1) {
throw new LogicException('Invalid Param : ' . $number);
}
return true;
}
}
これをテストしていきます。
@expectedException
テストするコードで例外がスローされたかどうかを判定するアノテーションです。
アノテーションに、判定したい例外クラスを指定してください。
/**
* @test
* @expectedException LogicException
*/
public function checkNumberOwnTestExcept()
{
$obj = new Example();
$obj->checkNumberOwn(2);
}
@expectedExceptionMessage
テストするコードでスローされた例外のメッセージを判定するアノテーションです。
アノテーションに、判定したいメッセージを指定してください。
メッセージは一部でも、判定することができます。
/**
* @test
* @expectedException LogicException
* @expectedExceptionMessage Invalid Param
*/
public function checkNumberOwnTestMessage()
{
$obj = new Example();
$obj->checkNumberOwn(2);
}
@expectedExceptionMessageRegExp
テストするコードでスローされた例外のメッセージを、正規表現で判定するアノテーションです。
アノテーションに、判定したいメッセージを指定してください。
/**
* @test
* @expectedException LogicException
* @expectedExceptionMessageRegExp /Invalid Param : /
*/
public function checkNumberOwnTestMessage()
{
$obj = new Example();
$obj->checkNumberOwn(2);
}
これらを使うことで、テストが冗長的になることを防げるかなと思います。
参考までに、テストコードはこちらに上げました。
気になること
複数の例外やエラーメッセージを1つのメソッドでやろうと思ったのですが、単純にアノテーションを複数セットするだけではだめでした…。
モデルでPDOException
とLogicException
を投げる、とかを1つのテストメソッドではできないのか…。
@tadsanさんにご教授頂き、$this->expectException()
や$this->expectExceptionMessage()
で複数の例外やエラーメッセージをチェック出来ることがわかりました。
ご教授ありがとうございました!
public function checkExceptionDataProvider():array
{
return [
'number 1' => [1, \LogicException::class, 'number 1'],
'number 2' => [2, \ErrorException::class, 'number 2'],
];
}
/**
* @test
* @dataProvider checkExceptionDataProvider
*/
public function checkExceptionTest($param, $errorClass, $errorMessage)
{
$this->expectException($errorClass);
$this->expectExceptionMessage($errorMessage);
$obj = new Example();
$obj->checkExecption($param);
}