こんにちは。よっしーです(^^)
今日は、PHPUnitで例外発生をテストするテストケースについてご紹介します。
前提
この記事は下記の記事をベースにしています。
背景
先日、PHPUnitの環境構築をしましたので、今回はexpectException() メソッドを使用して、テスト対象のコードによって例外がスローされるかどうかをテストする方法を示しています。
修正内容
下記のファイルを更新、もしくは、作成します。下記の各セクションに各ファイルの修正内容を記載しています。
new file: 19_learn_phpunit/tests/ExceptionTest.php
tests/ExceptionTest.php
下記の内容で新規作成します。
<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;
final class ExceptionTest extends TestCase
{
public function testException(): void
{
$this->expectException(InvalidArgumentException::class);
}
}
動作確認
下記のコマンドを実施します。
docker compose run -it --rm php-cmd ./vendor/bin/phpunit tests/ExceptionTest.php
下記の結果になれば成功です。
% docker compose run -it --rm php-cmd ./vendor/bin/phpunit tests/ExceptionTest.php
[+] Building 0.0s (0/0)
[+] Building 0.0s (0/0)
PHPUnit 10.2.6 by Sebastian Bergmann and contributors.
Runtime: PHP 8.1.12-1ubuntu4.2
F 1 / 1 (100%)
Time: 00:00.069, Memory: 8.00 MB
There was 1 failure:
1) ExceptionTest::testException
Failed asserting that exception of type "InvalidArgumentException" is thrown.
FAILURES!
Tests: 1, Assertions: 1, Failures: 1.
解説
tests/ExceptionTest.php
提供しているPHPコードは、PHPUnitを使用したユニットテストの例です。このテストは、expectException
メソッドを使用して、特定の例外が発生することをテストしています。以下がコードの詳細です:
<?php declare(strict_types=1);
: これはPHPのオープニングタグで、strict typeの宣言を含んでおり、厳密な型チェックが有効になっています。use PHPUnit\Framework\TestCase;
: この行は、PHPUnit\FrameworkネームスペースからTestCase
クラスをインポートしています。このクラスは、テストケースを記述するための基本的な機能を提供します。final class ExceptionTest extends TestCase
: この行は、ExceptionTest
クラスを定義しています。これは、PHPUnitのTestCase
クラスを継承したテストクラスです。ここでのfinal
キーワードは、他のクラスがこのテストクラスを継承するのを防ぎます。public function testException(): void
: この行は、testException
というテストメソッドを定義しています。PHPUnitのテストメソッドは、test
接頭辞を持つ必要があります。$this->expectException(InvalidArgumentException::class);
: この行は、テストメソッドがInvalidArgumentException
をスローすることを期待していることを示しています。つまり、このテストは、特定のコードがInvalidArgumentException
を引き起こすかどうかを確認しています。
テスト自体は以下のようになります:
<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;
final class ExceptionTest extends TestCase
{
public function testException(): void
{
// InvalidArgumentExceptionをスローすることが期待されるコード
$this->expectException(InvalidArgumentException::class);
// InvalidArgumentExceptionをスローするはずの関数を呼び出します
yourFunctionThatShouldThrowInvalidArgumentException();
}
}
なお、本記事のコードでは、yourFunctionThatShouldThrowInvalidArgumentException()
は提供されていません。これは、テストしたい具体的なユースケースに依存します。あなたがテストしたい特定の関数やコードブロックに、yourFunctionThatShouldThrowInvalidArgumentException()
を置き換える必要があります。
expectException() メソッド
expectException() メソッドは、スローされると予想される例外がスローされる前に使用する必要があります。expectException()は、例外がスローされると予想されるコードが呼び出される直前に呼び出されるのが理想的です。
expectException() メソッドに加えて、 expectExceptionCode() メソッド、 expectExceptionMessage() メソッド、 expectExceptionMessageMatches() メソッドがあり、テスト対象のコードで発生する例外に対する期待値を設定します。
expectExceptionMessage() は、$actual メッセージが $expected メッセージを含むことを保証し、 文字列の正確な比較は行わないことに注意しましょう。
返り値の保証と例外の予想は、テストメソッドでもっともよく行われる 3 つの操作のうちのふたつです。三つ目は副作用の検証です。オブジェクト連携における副作用の検証については、 後ほど説明します。
おわりに
今日は、PHPUnitで例外発生をテストするテストケースについてご紹介しました。
本記事でご紹介したソースは、下記のリポジトリにあります。
https://github.com/Gate-Yossi/Ran/releases/tag/v2023.08.07
何か質問や相談があれば、遠慮なくコメントしてください。また、エンジニア案件についても、いつでも相談にのっていますので、お気軽にお問い合わせください。
それでは、また明日お会いしましょう(^^)
コメント