如何在模拟测试中设置受保护的var的值(CakePHP)

时间:2016-06-20 10:33:10

标签: cakephp mocking phpunit cakephp-2.6

我想测试一个调用API的Shell。 Shell有一个函数,用于设置受保护的var protected $_credential = [];

的值
class ImportShell extends AppShell
{
    protected $_credential = [];

    public function sales() {
        $credential = $this->Credential->find('first', [
            'conditions' => [
                'Credential.id' => $this->args[0]
            ]
        ]);
        $this->_credential = $credential;
    }
}

它使用$this->args中的值来查找表条目并将结果写入$_credential

当我像这样使用时,如何在测试中访问/更改$_credential

$ImportShell = $this->getMockBuilder('ImportShell')
    ->setMethods(array('find'))
    ->getMock();

$ImportShell->sales();

另外,我如何访问/更改$this->args

1 个答案:

答案 0 :(得分:1)

使用反射

Reflections提供了一种修改和查询代码的机制,并具有set a property value的特定功能。语法有点不合理,但这允许您修改类属性(和函数)的可访问性和值。像这样的东西会做你想要的:

$class = new ReflectionClass("ImportShell");
$property = $class->getProperty("_credential");
$property->setAccessible(true);

$ImportShell = $this->getMockBuilder('ImportShell')
    ->setMethods(array('find'))
    ->getMock();
$ImportShell->_credential = ['stuff'];

的插件

Friends Of Cake Test Utilities plugin简化了语法以实现相同的功能。使用此插件的语法是:

$this->setProtectedProperty('_credential', ['stuff'], $ImportShell);

虽然真的有必要吗?

args is a public property。在调用测试函数之前,可以简单地设置用于填充它的公共属性,而不是操作受保护的属性。

$ImportShell = $this->getMockBuilder('ImportShell')
    ->setMethods(array('find'))
    ->getMock();

$ImportShell->args = ['stuff'];
$ImportShell->sales();

虽然给出了问题的表达方式,但是嘲笑Credential模型并添加一个期望它被调用并返回你想要的内容可能更有意义。