Per*_*n93 5 php phpunit unit-testing
我环顾四周,找到了一个适用于普通对象的解决方案,但它似乎不适用于模拟。
下面的测试失败并显示消息:Unable to set property someProperty of object type Mock_ClassToTest_40ea0b83: Property someProperty does not exist。
class sampleTestClass extends PHPUnit_Framework_TestCase
{
function test() {
$object = $this->getMockForAbstractClass(ClassToTest::class, [], '', false);
$this->setProtectedProperty($object, 'someProperty', 'value');
}
private function getReflectionProperty($object, $property) {
$reflection = new ReflectionClass($object);
$reflectionProperty = $reflection->getProperty($property);
$reflectionProperty->setAccessible(true);
return $reflectionProperty;
}
/**
* This method modifies the protected properties of any object.
* @param object $object The object to modify.
* @param string $property The name of the property to modify.
* @param mixed $value The value to set.
* @throws TestingException
*/
function setProtectedProperty(&$object, $property, $value) {
try {
$reflectionProperty = $this->getReflectionProperty($object, $property);
$reflectionProperty->setValue($object, $value);
}
catch ( Exception $e ) {
throw new TestingException("Unable to set property {$property} of object type " . get_class($object) .
': ' . $e->getMessage(), 0, $e);
}
}
}
abstract class ClassToTest
{
private $someProperty;
abstract function someFunc();
}
class TestingException extends Exception
{
}
Run Code Online (Sandbox Code Playgroud)
编辑:美国东部时间 2016 年 8 月 31 日下午 4:32 更新了代码以响应Katie 的回答。
您尝试在模拟对象上调用反射方法,相反,您可以在抽象类本身上调用它:
所以改变:
$reflection = new ReflectionClass(get_class($object));
Run Code Online (Sandbox Code Playgroud)
到
$reflection = new ReflectionClass(ClassToTest::class);
Run Code Online (Sandbox Code Playgroud)
这适用于类中非抽象的任何内容,例如您的属性或完全实现的其他方法。
自 OP 更新以来的附加说明
该修复仍然适用于 getReflectionProperty 中的第一行。但如果您无权访问类名,那就是一个问题。