如何为抽象类设置模拟的受保护属性?

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 的回答

Kat*_*tie 3

您尝试在模拟对象上调用反射方法,相反,您可以在抽象类本身上调用它:

所以改变:

$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 中的第一行。但如果您无权访问类名,那就是一个问题。