У меня такой код:
class ToBeTested { function simpleMethod($param) { if(0 === $param) { trigger_error("Param is 0!", E_USER_WARNING); return false; } return true; } }
и проверьте этот код:
class SimpleTest extends PHPUnit_Framework_TestCase { function testSimpleMethod() { $toBeTestedObject = new ToBeTested(); $this->assertFalse($toBeTestedObject->simpleMethod(0)); } }
Я знаю, как тестировать, если ошибка запускается ( $this->setExpectedException()
), но я не знаю, как выполнить код после функции trigger_error()
.
Помните, что в PHPUnit E_USER_WARNING
не преобразуется в PHPUnit_Framework_Error_Warning
(который может быть отключен), но он преобразуется в PHPUnit_Framework_Error
(который нельзя отключить).
Это одно из тех мест, где вам «официально» разрешено использовать оператор @ 🙂
Сделайте один тест, чтобы проверить возвращаемое значение, еще один тест, чтобы проверить, вызвано ли предупреждение. И, кстати, я предлагаю вам проверить, срабатывает ли предупреждение.
class SimpleTest extends PHPUnit_Framework_TestCase { function testSimpleMethodReturnValue() { $toBeTestedObject = new ToBeTested(); $this->assertFalse(@$toBeTestedObject->simpleMethod(0)); } /** * @expectedException PHPUnit_Framework_Error */ function testSimpleMethodEmitsWarning() { $toBeTestedObject = new ToBeTested(); $toBeTestedObject->simpleMethod(0); } }
Ответ заключается в том, что в PHPUnit 3.4.15 есть класс handleError
методом handleError
который выполняется при возникновении любой ошибки. Для ошибки, такой как E_USER_*
этот метод всегда выдает PHPUnit_Framework_Error
, поэтому выполнение остальной части кода останавливается.
Думаю, единственный способ предотвратить это – отключить отчеты об ошибках пользователей. Это можно сделать так:
class SimpleTest extends PHPUnit_Framework_TestCase { function testSimpleMethod() { $toBeTestedObject = new ToBeTested();
// disable user errors reporting $oldReportingLevel = error_reporting(); error_reporting($oldReportingLevel ^ (E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE));
// check the condition $this->assertFalse($toBeTestedObject->simpleMethod(0));
// recover old error reporting level error_reporting($oldReportingLevel); } }
То, что вы должны использовать, – set_error_handler()
( link ) и restore_error_handler()
который позволяет вам устанавливать функцию для обработки ошибок определенного типа. Он также имеет дополнительный бонус, предоставляя вам место для проверки предупреждения одновременно.
Итак, что-то вроде этого:
class SimpleTest extends PHPUnit_Framework_TestCase { function testSimpleMethod() { set_error_handler(array($this, '_handleWarnedMethod'), E_USER_WARNING); $toBeTestedObject = new ToBeTested(); $this->assertFalse($toBeTestedObject->simpleMethod(0)); restore_error_handler(); } private function _handleWarnedMethod($errno, $errstr) { $this->assertEquals(E_USER_WARNING, $errno); $this->assertEquals('Param is 0!', $errstr); } }
Как всегда, подавление ошибок – это не лучшая идея 🙂