Кто-нибудь знает, есть ли 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
чтобы получить имя класса с 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()); }
Вы можете использовать расширение assertException для утверждения более одного исключения во время одного теста.
Вставьте метод в свою тестовую базу и используйте:
public function testSomething() { $test = function() { // some code that has to throw an exception }; $this->assertException( $test, 'InvalidArgumentException', 100, 'expected message' ); }
Я также сделал черту для любовников хорошего кода.
public function testException() { try { $this->methodThatThrowsException(); $this->fail("Expected Exception has not been raised."); } catch (Exception $ex) { $this->assertEquals($ex->getMessage(), "Exception message"); } }
Альтернативным способом может быть следующее:
$this->expectException(\Exception::class); $this->expectExceptionMessage('Expected Exception Message');
Убедитесь, что ваш тестовый класс extents \ PHPUnit_Framework_TestCase
Вот все утверждения, которые вы можете сделать. Обратите внимание, что все они являются необязательными .
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); }
-/** * @expectedException Exception * @expectedExceptionMessage Amount has to be bigger then 0! */ public function testDepositNegative() { $this->account->deposit(-7); }
Будьте очень осторожны в отношении "/**"
, обратите внимание на двойную «*». Написание только «**» (asterix) приведет к отказу вашего кода. Также убедитесь, что вы используете последнюю версию phpUnit. В некоторых более ранних версиях phpunit @expectedException Exception не поддерживается. У меня было 4.0, и это не сработало для меня, мне пришлось обновить до 5.5 https://coderwall.com/p/mklvdw/install-phpunit-with-composer, чтобы обновить композитор.
Метод PHPUnit expectException
очень неудобен, потому что он позволяет протестировать только одно исключение в тестовом методе.
Я сделал эту вспомогательную функцию, чтобы утверждать, что некоторая функция генерирует исключение:
/** * 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); 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'); }); }