使用PHPUnit测试error_log

时间:2015-07-26 12:41:41

标签: php phpunit

我有这个功能,我想测试看起来像这样:

class Logger {
  function error($msg){
    if (is_string($msg)){
      error_log($msg);
      die($msg);
    } elseif (is_object($msg)){
      error_log($msg.' '.$msg->getTraceAsString());
      die('exception');
    } else {
      var_dump($msg);
      die('error');
    }
  }

我想在不记录$msg的情况下测试此功能。有没有办法确定error_log是否可以在没有记录的情况下工作?我尝试使用setExpectedException,但我无法捕获错误,并且一直在记录。

2 个答案:

答案 0 :(得分:8)

显而易见的答案是一个简单的别名/代理函数,它本身在Logger类中调用error_log(可以很容易地模拟,并检查以查看设置它的内容),

要实际测试本机error_log函数(在原始类中没有代理),可以使用名称空间来完成。最终将测试定义为与原始代码相同的命名空间,然后在测试类之后添加一个函数 - 在本例中为error_log() - 但该函数也在命名空间中定义 - 因此将是优先于本机函数的root-namespace-equivalent运行。

很遗憾,您无法对die(或其别名exit)执行相同的覆盖。它们是“语言结构”,不能像error_log那样被覆盖。

<?php
namespace abc;
use abc\Logger;

class ThreeTest extends \PHPUnit_Framework_TestCase
{
    public function setUp() { $this->l = new Logger(); }
    // test code to exercise 'abc\Logger'

}

// Now define a function, still inside the namespace '\abc'.
public function error_log($msg)
{
   // this will be called from abc\Logger::error
   // instead of the native error_log() function
   echo "ERR: $msg, ";
}

答案 1 :(得分:1)

你可以使用像php-mock这样的函数模拟框架(还有其他框架)来模拟对error_log的调用(并检查是否使用你期望的参数调用它)。

不幸的是,你不能将它用于die-construct,因为它不是正常的函数,而是anlanguage构造。

我用一个新的\ Exception()&#39;来替换die()。 (或任何其他适当的例外),你可以

  • 测试抛出的异常和
  • 可以在编程中决定是否在调用记录器时停止执行,或者是否要通过将调用包装到try / catch中继续执行

但是我也会问自己,在调用记录器时是否必须停止执行