我有这样的代码:
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
(无法禁用)。
答案 0 :(得分:11)
这是“官方”允许使用@运算符的地方之一:)
进行一项测试以检查返回值,另一项测试用于检查警告是否被触发。顺便说一句,如果触发警告,我建议你做测试。
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);
}
}
答案 1 :(得分:3)
您应该使用的是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);
}
}
与往常一样,错误抑制不是最好的主意:)
答案 2 :(得分:2)
答案是,在PHPUnit 3.4.15中,PHPUnit_Util_ErrorHandler
类具有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);
}
}
答案 3 :(得分:0)
近9年后,这个问题仍然经常出现。
您可以使用Netsilik/BaseTestCase(MIT许可证)来获得扩展的功能,以断言错误/警告将按预期方式触发:
composer require netsilik/base-test-case
测试E_WARNING
:
<?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');
}
}