php - 如何为抽象类设置模拟的 protected 属性?

标签 php unit-testing phpunit

我环顾四周,发现了一个适用于普通对象的解决方案,但它似乎不适用于模拟。

下面的测试失败并显示以下消息: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
{
}

编辑:2016 年 8 月 31 日美国东部时间下午 4:32
更新代码以响应 answer by Katie .

最佳答案

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

所以改变:

$reflection = new ReflectionClass(get_class($object));


$reflection = new ReflectionClass(ClassToTest::class);

这将适用于类中任何非抽象的东西,例如您的属性,或其他完全实现的方法。

OP 更新后的附加说明

该修复程序仍然适用于您在 getReflectionProperty 中的第一行。但是,如果您无权访问类名,那就有问题了。

关于php - 如何为抽象类设置模拟的 protected 属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39257217/

相关文章:

javascript - 添加 auto_increment id 列后无法使用 php 和 javascript 将数据添加到 mysql 数据库

php - 根据上一行的日期获取下一行的内容

php - Google Weather API - 解析和修改数据

unit-testing - 暂停可取消协程取消的 Kotlin Mockk 测试

javascript - PHP 表单写入原始 HTML 页面

java - 在java中测试两个dom元素是否相等

python - pytest(几乎)首先运行新测试

php - 如果测试访问器是浪费时间,那么测试构造函数逻辑呢?

PHPUnit::get message: 好的,但是测试不完整或跳过了!没有任何信息发生在哪里

PHPUnit 和 Selenium 示例 17.1