我发现了关于你是否测试私有方法的讨论。
我已经决定,在某些类中,我希望有受保护的方法,但要测试它们。
其中一些方法是静态的和简短的。因为大多数公共方法都使用了这些测试,所以我以后可能会安全地删除这些测试。但是为了从TDD方法开始并避免调试,我真的很想测试它们。
我想到了以下几点:
在回答中建议的方法对象似乎是多余的。
从公共方法开始,当代码覆盖由更高级别的测试提供时,将它们变为受保护的,并删除测试。
继承一个具有可测试接口的类,该接口使受保护的方法公开
哪种是最佳实践?还有别的事吗?
看起来,JUnit会自动将受保护的方法更改为公共方法,但我并没有深入了解它。PHP不允许通过反射进行此操作。
为了单元测试的目的,我做了一个类来调用简单的私有方法(静态和非静态):
class MethodInvoker
{
public function invoke($object, string $methodName, array $args=[]) {
$privateMethod = $this->getMethod(get_class($object), $methodName);
return $privateMethod->invokeArgs($object, $args);
}
private function getMethod(string $className, string $methodName) {
$class = new \ReflectionClass($className);
$method = $class->getMethod($methodName);
$method->setAccessible(true);
return $method;
}
}
用法示例:
class TestClass {
private function privateMethod(string $txt) {
print_r('invoked privateMethod: ' . $txt);
}
}
(new MethodInvoker)->invoke(new TestClass, 'privateMethod', ['argument_1']);
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)
);