PHPunit - 测试自定义错误处理类

ste*_*lin 2 php phpunit unit-testing

我想测试一下我放在一起的自定义错误处理类,但这本身就带来了一些问题.

首先,由于在测试中设置自定义error_handler会覆盖PHPUnits error_handling,每次将其更改为自定义实现并进行测试时,必须调用restore_error_handler(),以便以后的测试使phpunits error_handling.虽然我承认没有尝试过,但是每次测试后PHPUnit都会重置自己,我有点怀疑它.

我有各种配置来测试,在不同的条件下,即E_ERROR,E_WARNING等.

然后我有了嘲笑error_handler的想法,但在模拟测试方面仍然很绿.一个快速的谷歌搜索让我找到了类似的方法,这里的想法修改和实施的方式可能适合我的需要...

//Create mock with error_handler method
$errorH = $this->getMock ('ErrorHandler', array ('error_handler'));

// error handler should be called at least once
$errorH->expects ($this->atLeastOnce())->method ('error_handler');

// Mock will  need to be configured (here?) and tested 
// against specific error_handling settings 
//  not implemented yet nor needed for this post.

//set mock as error handler for duration of this test
set_error_handler (array($errorH, 'error_handler'));

//test current mock error handler configuration 
// for different conditions-> NOTICE / WARNING / ERROR

// Give phpunit's toy back!
restore_error_handler ();
Run Code Online (Sandbox Code Playgroud)

这是一种有效的方法吗?

Dav*_*ess 8

没有必要测试PHP的set_error_handler()功能.您只关心您的错误处理类是否有效.将测试PHP解释器留给PHP开发人员.:)像对待任何其他类一样对待你的类:实例化它并调用它的方法,传递参数来测试不同的条件.

例如,假设你的错误处理程序看起来像这样:

class ErrorHandler
{
    private $logger;

    private $mode;

    public function __construct($mode, $logger) {
        $this->mode = $mode;
        $this->logger = $logger;
    }

    public function handleError($code, $message, $file='', $line=0, $context=array()) {
        if ($code = E_WARNING && $this->mode == 'dev') {
            // warnings are logged in development mode
            $this->logger->log($message, Logger::WARN);
        }
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以使用模拟记录器测试上面的一个功能,而无需调用set_error_handler()或触发实际的PHP错误.相反,就像PHP在这些条件下那样调用你的错误处理程序:

function testWarningsAreLoggedInDevelopment() {
    $logger = $this->getMock('Logger', array('log'));
    $logger->expects($this->once())
           ->method('log')
           ->with('message', Logger::WARN);
    $handler = new ErrorHandler('dev', $logger);
    $handler->handleError(E_WARNING, 'message');
}
Run Code Online (Sandbox Code Playgroud)

美妙的是,如果您的错误处理程序由于错误而触发PHP错误,PHPUnit将捕获它并使测试失败.如果用你自己的PHPUnit替换PHPUnit的处理程序,你可能会进入一个无限循环,因为PHP一遍又一遍地调用你的处理程序,直到解释器从堆栈溢出或内存不足中消失.

  • @stefgosselin - 我的意思是PHP将使用`set_error_handler()`调用你指定的方法,并且不需要测试那个方面.相反,编写测试直接调用该方法并传入适当的参数.我将在我的答案中添加一个示例来说明. (3认同)