LoginSignup
0
0

More than 5 years have passed since last update.

PHP5系と7系共通でassertion例外を発生させる方法

Last updated at Posted at 2019-03-06

TL;DR

PHP5系および7系のassertion失敗時に例外を発生させたい場合はASSERT_CALLBACKにて自分で記述する。

シチュエーション例

5系および7系をサポートしたいSDKに関して、ユニットテストとは別にシナリオテスト(smoke test)をassertionを使って書いた。
assertion失敗時はtry-catch(-finally)内でcleanup処理をさせたい(ex, DBからテストデータを削除)。

PHPのassert

デフォルトではWarningを発生させるだけで正常終了する。

$php -r 'assert(false, "myTest");'
Warning: assert(): myTest failed in Command line code on line 1

ユニットテストとは別にシナリオテスト(smoke test)をassertionで書いた時、AssertionErrorなど例外終了させたかった。

PHP7系からassert.exceptionディレクティブを設定でき、 このモードPHP_INI_ALLなのでphp.iniの他ini_set()で設定できる。

<?php
ini_set('assert.exception', '1');
assert(false, "myTest"); // Fatal error: Uncaught AssertionError: myTest in /tmp/sample.php:3 + Stack trace(省略)
echo 'not display';

ただし対象のスクリプトは5系サポートもしたい。

5系ではassert.exceptionディレクティブはないため、上記のスクリプトはini_set()が無視され、assertのWarningとechoが出力されてしまう。

5系および7系で共通して使えるのはassert_options()というビルトイン関数で、その中に直接的に例外を発生させるオプションは存在しない。

ASSERT_CALLBACKオプションでassertion失敗時の任意のコールバックを渡せるので、そこで例外発生させる。

<?php
assert_options(ASSERT_CALLBACK, 'assertionError');

function assertionError($script, $line, $message)
{
    throw new Exception();
}

try {
    assert(false); // Warning: assert(): assert(false) failed in /tmp/sample.php on line 10
    echo "not display\n";
} catch(Exception $e) {
    echo "cleanup\n"; // cleanup
}

ASSERT_BAILというオプションもあるが、これはexitしてしまうのでtry-catchなどで捕捉できない。
ただしASSERT_CALLBACKは呼ばれるので、コールバック内でcleanupする手もあるが、特定のテストデータをクリーンしたい場合は引数が固定のためglobalなどで渡す必要がある。

0
0
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
0
0