テスト対象のコードに例外がスローされたかどうかをテストできるassert
またはそのようなものがあるかどうかを知っている人はいますか?
<?php
require_once 'PHPUnit/Framework.php';
class ExceptionTest extends PHPUnit_Framework_TestCase
{
public function testException()
{
$this->expectException(InvalidArgumentException::class);
// or for PHPUnit < 5.2
// $this->setExpectedException(InvalidArgumentException::class);
//...and then add your test code that generates the exception
exampleMethod($anInvalidArgument);
}
}
expectException()PHPUnitドキュメント
PHPUnit作者の記事 例外のテストのベストプラクティスに関する詳細な説明があります。
docblockアノテーション を使うこともできます。
class ExceptionTest extends PHPUnit_Framework_TestCase
{
/**
* @expectedException InvalidArgumentException
*/
public function testException()
{
...
}
}
PHP 5.5以降(特に名前空間付きコードの場合)には、 ::class
を使うことをお勧めします。
PHP 5.5以降で実行している場合、 ::class
resolution を使用して expectException
/setExpectedException
でクラスの名前を取得できます。これにはいくつかの利点があります。
string
に解決されるので、あらゆるバージョンのPHPUnitで動作します。例:
namespace \My\Cool\Package;
class AuthTest extends \PHPUnit_Framework_TestCase
{
public function testLoginFailsForWrongPassword()
{
$this->expectException(WrongPasswordException::class);
Auth::login('Bob', 'wrong');
}
}
PHPコンパイル
WrongPasswordException::class
に
"\My\Cool\Package\WrongPasswordException"
pHPUnitが賢くないこと。
注: PHPUnit 5.2が導入されました
expectException
の代わりとしてのsetExpectedException
。
以下のコードは、例外メッセージと例外コードをテストします。
重要:期待される例外も投げられないと失敗します。
try{
$test->methodWhichWillThrowException();//if this method not throw exception it must be fail too.
$this->fail("Expected exception 1162011 not thrown");
}catch(MySpecificException $e){ //Not catching a generic Exception or the fail function is also catched
$this->assertEquals(1162011, $e->getCode());
$this->assertEquals("Exception Message", $e->getMessage());
}
1回のテスト実行中に複数の例外を表明するには、 assertException extension を使用できます。
TestCaseにmethodを挿入して、
public function testSomething()
{
$test = function() {
// some code that has to throw an exception
};
$this->assertException( $test, 'InvalidArgumentException', 100, 'expected message' );
}
私はNiceコードを愛する人のために trait も作りました..
代替方法は次のようになります。
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Expected Exception Message');
あなたのテストクラスが\PHPUnit_Framework_TestCase
を拡張していることを確認してください。
public function testException() {
try {
$this->methodThatThrowsException();
$this->fail("Expected Exception has not been raised.");
} catch (Exception $ex) {
$this->assertEquals($ex->getMessage(), "Exception message");
}
}
例外テストのためのPHPUnitの現在の " ベストプラクティス "は艶がありません( docs )。
私は---現在のexpectException
の実装よりも もっと欲しい なので、私は自分のテストケースで使うための特性を作りました。それは 〜50行のコード だけです。
assert
の構文assertNotThrows
をサポートThrowable
エラーをサポートAssertThrows
Githubへのトレイトと packagist を公開しましたので、composerでインストールすることができます。
構文の背後にある精神を説明するためだけに:
<?php
// Using simple callback
$this->assertThrows(MyException::class, [$obj, 'doSomethingBad']);
// Using anonymous function
$this->assertThrows(MyException::class, function() use ($obj) {
$obj->doSomethingBad();
});
かなりきれい?
より包括的な使用例については、以下を参照してください。
<?php
declare(strict_types=1);
use Jchook\AssertThrows\AssertThrows;
use PHPUnit\Framework\TestCase;
// These are just for illustration
use MyNamespace\MyException;
use MyNamespace\MyObject;
final class MyTest extends TestCase
{
use AssertThrows; // <--- adds the assertThrows method
public function testMyObject()
{
$obj = new MyObject();
// Test a basic exception is thrown
$this->assertThrows(MyException::class, function() use ($obj) {
$obj->doSomethingBad();
});
// Test custom aspects of a custom extension class
$this->assertThrows(MyException::class,
function() use ($obj) {
$obj->doSomethingBad();
},
function($exception) {
$this->assertEquals('Expected value', $exception->getCustomThing());
$this->assertEquals(123, $exception->getCode());
}
);
// Test that a specific exception is NOT thrown
$this->assertNotThrows(MyException::class, function() use ($obj) {
$obj->doSomethingGood();
});
}
}
?>
PHPUnitのexpectException
メソッドは、テストメソッドごとに1つの例外しかテストできないため、非常に不便です。
私はこのヘルパー関数を作成して、ある関数が例外を投げることを主張しました:
/**
* Asserts that the given callback throws the given exception.
*
* @param string $expectClass The name of the expected exception class
* @param callable $callback A callback which should throw the exception
*/
protected function assertException(string $expectClass, callable $callback)
{
try {
$callback();
} catch (\Throwable $exception) {
$this->assertInstanceOf($expectClass, $exception, 'An invalid exception was thrown');
return;
}
$this->fail('No exception was thrown');
}
それをテストクラスに追加して、このように呼び出します。
public function testSomething() {
$this->assertException(\PDOException::class, function() {
new \PDO('bad:param');
});
$this->assertException(\PDOException::class, function() {
new \PDO('foo:bar');
});
}
これがあなたができるすべての例外アサーションです。それらはすべてオプションであることに注意してください。
class ExceptionTest extends PHPUnit_Framework_TestCase
{
public function testException()
{
// make your exception assertions
$this->expectException(InvalidArgumentException::class);
// if you use namespaces:
// $this->expectException('\Namespace\MyException');
$this->expectExceptionMessage('message');
$this->expectExceptionMessageRegExp('/essage$/');
$this->expectExceptionCode(123);
// code that throws an exception
throw new InvalidArgumentException('message', 123);
}
public function testAnotherException()
{
// repeat as needed
$this->expectException(Exception::class);
throw new Exception('Oh no!');
}
}
ドキュメントは こちら で見つけることができます。
/**
* @expectedException Exception
* @expectedExceptionMessage Amount has to be bigger then 0!
*/
public function testDepositNegative()
{
$this->account->deposit(-7);
}
"/**"
については非常に注意してください。二重の "*"に注意してください。 "**"(アスタリスク)のみを書くとコードが失敗します。また、phpUnitの最後のバージョンを使用していることを確認してください。以前のバージョンのphpunit @expectedExceptionでは、例外はサポートされていません。私は4.0を持っていました、そしてそれは私のために働きませんでした、私は5.5にアップデートしなければなりませんでした https://coderwall.com/p/mklvdw/install-phpunit-with-composer 作曲家とアップデートするために。
PHPUnit 5.7.27とPHP 5.6では、1回のテストで複数の例外をテストするために、例外テストを強制することが重要でした。例外処理を単独で使用してExceptionのインスタンスをアサートすると、例外が発生しない場合は状況のテストがスキップされます。
public function testSomeFunction() {
$e=null;
$targetClassObj= new TargetClass();
try {
$targetClassObj->doSomething();
} catch ( \Exception $e ) {
}
$this->assertInstanceOf(\Exception::class,$e);
$this->assertEquals('Some message',$e->getMessage());
$e=null;
try {
$targetClassObj->doSomethingElse();
} catch ( Exception $e ) {
}
$this->assertInstanceOf(\Exception::class,$e);
$this->assertEquals('Another message',$e->getMessage());
}
function yourfunction($a,$z){
if($a<$z){ throw new <YOUR_EXCEPTION>; }
}
ここにテストがあります
class FunctionTest extends \PHPUnit_Framework_TestCase{
public function testException(){
$this->setExpectedException(<YOUR_EXCEPTION>::class);
yourfunction(1,2);//add vars that cause the exception
}
}