🚀

PHPUnitで例外のテストを書く方法

2023/01/09に公開

PHPUnitで例外のテストを書きたい時はexpectException()を使いましょう。

<?php

use PHPUnit\Framework\TestCase;

final class ExceptionTest extends TestCase
{
    public function testException(): void
    {
        $this->expectException(InvalidArgumentException::class);
	
	// テスト対象の処理を呼び出す
    }
}

expectException()は例外が発生する処理の前に書いておく必要があります。
また、以下のように例外メッセージや例外コードをテストすることも可能です。

final class ExceptionTest extends TestCase
{
    public function testException(): void
    {
        $this->expectException(InvalidArgumentException::class);
        $this->expectExceptionCode(0);
        $this->expectExceptionMessage('invalid');
        $this->expectExceptionMessageMatches('/invalid/');

        // テスト対象の処理を呼び出す
    }
}

expectExceptionMessage()は完全一致を確認しているわけではなく、文字列が含まれているかの確認なので注意が必要です。

// 'invalid'というメッセージだった場合
$this->expectExceptionMessage('in');  // これはpassする
$this->expectExceptionMessage('is');  // これはfailとなる

古いPHPUnitだとexpectExceptionは使えない

古いバージョンのPHPUnitだとexpectException()が使えません。PHPUnitのバージョンを上げられれば良いのですが、なかなかそうもいかないことが多いでしょう。
その場合は、以下のメソッドで同等のテストが可能です。

$this->setExpectedException('InvalidArgumentException');
$this->setExpectedExceptionRegExp('InvalidArgumentException', '/invalid/', 0);

古いバージョンのPHPUnitの場合で他にもアノテーションを使うやり方(@expectedExceptionなど)が紹介されていることもありますが、setExpectedException()やsetExpectedExceptionRegExp()を使う方法をオススメします。
アノテーションだとtypoなどで書き方が間違っていてもエラーが拾えず、テストが正しく書かれていなかったとしてもそれに気づけないためです。

Discussion