Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在单元测试(PHPUnit)中触发错误(…,E_用户警告)后如何执行代码?_Php_Unit Testing_Phpunit - Fatal编程技术网

在单元测试(PHPUnit)中触发错误(…,E_用户警告)后如何执行代码?

在单元测试(PHPUnit)中触发错误(…,E_用户警告)后如何执行代码?,php,unit-testing,phpunit,Php,Unit Testing,Phpunit,我有这样的代码: 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 {

我有这样的代码:

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()
   {
     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);
   }

}
并测试此代码:

class SimpleTest extends PHPUnit_Framework_TestCase
{
   function testSimpleMethod()
   {
     $toBeTestedObject = new ToBeTested();
     $this->assertFalse($toBeTestedObject->simpleMethod(0));
   }
}
我知道如何测试是否触发了错误(
this->setExpectedException()
),但我不知道在
trigger\u error()
函数之后如何执行代码


请记住,在PHPUnit
E\u中,用户\u警告
不会转换为
PHPUnit\u框架错误\u警告
(可以禁用),但会转换为
PHPUnit\u框架错误
(不能禁用).

答案是在PHPUnit 3.4.15中有
PHPUnit\u Util\u ErrorHandler
类和
handleError
方法,该方法在发生任何错误时执行。对于像
E\u USER.*
这样的错误,此方法总是抛出
PHPUnit\u Framework\u错误
,因此停止执行其余代码

我认为,防止这种情况发生的唯一方法是禁用用户错误报告。可以这样做:

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()
   {
     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);
   }

}

类SimpleTest扩展了PHPUnit_框架_测试用例
{
函数testSimpleMethod()
{
$toBeTestedObject=新的ToBeTested();
//禁用用户错误报告 $oldReportingLevel=错误报告(); 错误报告($oldReportingLevel^(E_用户错误| E_用户警告| E_用户通知));
//检查情况 $this->assertFalse($toBeTestedObject->simpleMethod(0));
//恢复旧的错误报告级别 错误报告($oldReportingLevel); } }

这是允许您“正式”使用@operator:)的地方之一

进行一次测试以检查返回值,另一次测试以检查是否触发了警告。顺便说一下,我建议你测试一下是否触发了警告

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);
   }
}

您应该使用的是
set\u error\u handler()
()和
restore\u error\u handler()
,它允许您设置一个函数来处理给定类型的错误。同时,它还为您提供了一个测试警告的位置

比如说:

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()
   {
     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);
   }

}

一如既往,错误抑制并不是最好的主意:)

近9年后,这个问题仍然经常出现

您可以使用(MIT许可证)获得扩展功能,以断言错误/警告按预期触发:

composer需要netsilik/base测试用例


测试是否存在
E_警告

<?php
namespace Tests;

class MyTestCase extends \Netsilik\Testing\BaseTestCase
{
    /**
     * {@inheritDoc}
     */
    public function __construct($name = null, array $data = [], $dataName = '')
    {
        parent::__construct($name, $data, $dataName);

        $this->_convertNoticesToExceptions  = false;
        $this->_convertWarningsToExceptions = false;
        $this->_convertErrorsToExceptions   = true;
    }

    public function test_whenWarningTriggered_weCanTestForIt()
    {
        $foo = new Foo();
        $foo->bar();

        self::assertErrorTriggered(E_WARNING, 'The warning string');
    }
}

谢谢你的回答。使用@character.:)看起来确实是一个很好的例子这仍然被认为是测试
E_USER_WARNING
的正确方法吗?@tereško是的。这仍然是我意识到的唯一一种理智的方式。首先测试警告,然后测试错误可能是有意义的,因此在E_致命事件的情况下,错误抑制将关闭。但是,
xdebug.scream
也总是在那里:)@BobStein VisiBone谢谢。非常受欢迎的PHP.net文档:PHP支持一个错误控制操作符:at符号(@)。在PHP中,在表达式前面加上前缀时,将忽略该表达式可能生成的任何错误消息。