使用 PHPUnit 测试受保护方法的最佳实践

2022-08-30 06:02:03

我发现关于你是否测试私人方法的讨论内容丰富。

我已经决定,在某些类中,我想要受保护的方法,但要测试它们。其中一些方法是静态和简短的。由于大多数公共方法都使用它们,因此我以后可能会安全地删除测试。但是,为了从TDD方法开始并避免调试,我真的想测试它们。

我想到了以下几点:

  • 答案中建议的方法对象似乎对此有些过分。
  • 从公共方法开始,当更高级别的测试给出代码覆盖率时,将它们置于受保护状态并删除测试。
  • 继承具有可测试接口的类,使受保护的方法公开

哪种是最佳做法?还有别的吗?

看起来,JUnit会自动将受保护的方法更改为公开,但我没有更深入地研究它。PHP 不允许通过反射执行此操作。


答案 1

如果您将 PHP5 (>= 5.3.2) 与 PHPUnit 配合使用,则可以在运行测试之前使用反射将私有和受保护的方法设置为公共方法,以测试这些方法:

protected static function getMethod($name) {
  $class = new ReflectionClass('MyClass');
  $method = $class->getMethod($name);
  $method->setAccessible(true);
  return $method;
}

public function testFoo() {
  $foo = self::getMethod('foo');
  $obj = new MyClass();
  $foo->invokeArgs($obj, array(...));
  ...
}

答案 2

Teastburn有正确的方法。更简单的是直接调用该方法并返回答案:

class PHPUnitUtil
{
  public static function callMethod($obj, $name, array $args) {
        $class = new \ReflectionClass($obj);
        $method = $class->getMethod($name);
        $method->setAccessible(true);
        return $method->invokeArgs($obj, $args);
    }
}

您可以通过以下方式在测试中简单地调用它:

$returnVal = PHPUnitUtil::callMethod(
                $this->object,
                '_nameOfProtectedMethod', 
                array($arg1, $arg2)
             );

推荐