Intereting Posts

PHPUnit утверждает, что было выбрано исключение?

Кто-нибудь знает, есть ли 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.
  • Вы получаете завершение кода в своей среде IDE.
  • Компилятор PHP выдает ошибку, если вы ошибочно называете имя класса.

Пример:

 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\MyExceptio‌​n'); $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'); }); }