2
2

More than 3 years have passed since last update.

PHPUnitの"expectException()"は、例外を発生させる箇所より前に記載する

Last updated at Posted at 2020-05-28

環境

$ 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

このメソッドは、例外発生箇所より手前で定義する必要があります。
上記公式ドキュメントのサンプルコードを借りて説明すると、

こうではなく、

ExceptionTest.php
<?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);

こうすべきです。

ExceptionTest.php
<?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()と仲良く暮らしていきましょう。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2