環境
$ vendor/bin/phpunit --version
PHPUnit 9.1.5 by Sebastian Bergmann and contributors.
$ php --version
PHP 7.4.0 (cli) (built: May 27 2020 22:16:49) ( NTS )
expectException()を記載したのに、例外を発生させてもテストが成功しなかった
記載する位置、順番を間違えていたのが原因でした。
PHPUnitには、テストコード内で例外が生成されたかを確認するexpectException
メソッドが実装されています。
https://phpunit.readthedocs.io/ja/latest/writing-tests-for-phpunit.html#writing-tests-for-phpunit-exceptions
このメソッドは、例外発生箇所より手前で定義する必要があります。
上記公式ドキュメントのサンプルコードを借りて説明すると、
こうではなく、
<?php
use PHPUnit\Framework\TestCase;
class ExceptionTest extends TestCase
{
public function testException()
{
throw new \InvalidArgumentException("ここでわざとエラーを出します。");
$this->expectException(\InvalidArgumentException::class);
}
}
こうやって変更して
- $this->expectException(\InvalidArgumentException::class);
throw new \InvalidArgumentException("ここでわざとエラーを出します。");
+ $this->expectException(\InvalidArgumentException::class);
こうすべきです。
<?php
use PHPUnit\Framework\TestCase;
class ExceptionTest extends TestCase
{
public function testException()
{
$this->expectException(\InvalidArgumentException::class);
throw new \InvalidArgumentException("ここでわざとエラーを出します。");
}
}
出力
実行結果です。こちらは、誤った順番で実行した場合
$ vendor/bin/phpunit ./tests/TDDPractice/ExceptionTest.php
PHPUnit 9.1.5 by Sebastian Bergmann and contributors.
E 1 / 1 (100%)
Time: 00:00.026, Memory: 4.00 MB
There was 1 error:
1) ExceptionTest::testException
\InvalidArgumentException: ここでわざとエラーを出します。
/home/taro/projects/phpsample/tests/TDDPractice/ExceptionTest.php:8
ERRORS!
Tests: 1, Assertions: 0, Errors: 1.
こちらが、正しい順番で実行した場合です。
$ vendor/bin/phpunit ./tests/TDDPractice/ExceptionTest.php
PHPUnit 9.1.5 by Sebastian Bergmann and contributors.
. 1 / 1 (100%)
Time: 00:00.045, Memory: 4.00 MB
OK (1 test, 1 assertion)
おわりに
メソッド名をよくよく考えれば、 "assertHoge()" のような名前ではなく、 "expectException" という名前が利用されています。
このニュアンスに気づいていれば、順番をひっくり返すこともなかったかもなと思います。
追記
@expectedException
という形式で、テストケースを記載することもできます。
...と書こうと思ったら、手元で動きませんでした。8.x系で非推奨となり、9.x系で削除されたようです。
https://github.com/gordalina/cachetool/issues/141
$this->expectException()
と仲良く暮らしていきましょう。