Как выполнить код после trigger_error (..., E_USER_WARNING) в модульном тесте (PHPUnit)? - PullRequest
4 голосов
/ 24 сентября 2010

У меня есть такой код:

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 (который не может быть отключен).

Ответы [ 3 ]

11 голосов
/ 27 сентября 2010

Это одно из тех мест, где вам «официально» разрешено использовать оператор @:)

Сделайте один тест, чтобы проверить возвращаемое значение, другой тест, чтобы проверить, срабатывает ли предупреждение.И, кстати, я бы посоветовал вам сделать тест, если предупреждение сработало.

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);
   }
}
3 голосов
/ 26 апреля 2012

То, что вы должны использовать, это set_error_handler() ( ссылка ) и 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);
   }

}

Как всегда, подавление ошибок - не лучшая идея:)

2 голосов
/ 24 сентября 2010

Ответ в том, что в PHPUnit 3.4.15 есть класс PHPUnit_Util_ErrorHandler с методом handleError, который выполняется при возникновении любой ошибки. Для ошибки типа E_USER_* этот метод всегда выдает PHPUnit_Framework_Error, поэтому выполнение остальной части кода останавливается.

Единственный способ предотвратить это - отключить создание отчетов об ошибках пользователей. Это можно сделать так:

<code>
class SimpleTest extends PHPUnit_Framework_TestCase
{
   function testSimpleMethod()
   {
      $toBeTestedObject = new ToBeTested();<br>
      // disable user errors reporting
      $oldReportingLevel = error_reporting();
      error_reporting($oldReportingLevel ^ (E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE));<br>
      // check the condition
      $this->assertFalse($toBeTestedObject->simpleMethod(0));<br>
      // recover old error reporting level
      error_reporting($oldReportingLevel);
   }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...