通过公共方法访问受保护的属性

时间:2017-10-17 09:57:43

标签: php phpunit mockery

我通过模拟类并测试函数调用来测试逻辑流程。

function() setUp() 
{
    $this->shipping_method = $this->getMockBuilder(Wc_Trincargo_Shipping_Method::class)
                    ->getMock();

    $this->shipping_method->set_post_data([
        'woocommerce_wc-trinicargo-shipping_waybill_password' => 'xxx',
        'woocommerce_wc-trinicargo-shipping_waybill_username' => 'xxxx',
        'woocommerce_wc-trinicargo-shipping_waybill_customer_id' => uniqid(),
        'woocommerce_wc-trinicargo-shipping_waybill_pickupdays' => 2
    ]);
}

set_post_data是一种设置受保护属性的公共方法。

稍后我测试调用另一个需要检查所述受保护属性的方法。我知道他们说你不能模仿受保护的私人财产,但如果这些财产是通过公共方法设定的......那不应该有效吗?

2 个答案:

答案 0 :(得分:1)

如果您确实需要在测试中访问受保护的属性并且您没有获取getter(也不应该仅为测试创建一个),则可以使用反射。

<?php

class MyClass
{
    protected $myProperty;

    public function setMyProperty($value) 
    {
        $this->myProperty = $value;
    }
}


$a = new MyClass();
$a->setMyProperty('TestValue');

// echo $a->myProperty; Can't do this because it's protected.

$r = new ReflectionProperty('MyClass', 'myProperty');
$r->setAccessible(true);
$value = $r->getValue($a);

echo $value; // 'TestValue'

答案 1 :(得分:0)

受保护的属性来自公共方法无关紧要。无论如何,可见性属于该属性。如果您之后需要检查属性的值,请为该属性创建一个公共getter。

请注意,测试简单的getter和setter是没用的。您应该测试类对属性值的作用。

无用测试的例子:

class MyClass {
    private $prop;
    public function setProp($value) {
        $this->prop = $value;
    }
    public function getProp() {
        return $this->prop;
    }
}

测试

$myClass = new MyClass();
$myClass->setProp('foo');
assertTrue($myClass->getProp() === 'foo');

以有意义的方式使用一个prop的类的示例,它确定另一个方法的行为/输出:

class MyClass2 {
    private $prop;
    public function setProp($value) {
        $this->prop = $value;
    }
    public function getPropUpperCase() {
        return strtoupper($this->prop);
    }
}

测试

$myClass2 = new MyClass();
$myClass2->setProp('foo');
assertTrue($myClass->getPropUpperCase() === 'FOO');