PHPUnit使用引用参数模拟一个控制器?

时间:2014-02-18 12:26:58

标签: zend-framework mocking phpunit

我有一个班级:

class Hello {
    function doSomething(&$reference, $normalParameter) {
       // do stuff...
    }
}

然后我有一个控制器:

class myController {
    function goNowAction() {
         $hello = new Hello();
         $var = new stdClass();
         $var2 = new stdClass();
         $bla = $hello->doSomething($var, $var2);
    }
}

我使用我的测试调用“goNow”动作:

$this->dispatch('/my/go-now');

我想嘲笑“doSomething”方法,所以它返回“GONOW!”这个词。作为结果。我该怎么做?

我尝试过创建模拟

$mock = $this->getMock('Hello ', array('doSomething'));

然后添加回报:

$stub->expects($this->any())
         ->method('discoverRoute2')
         ->will($this->returnValue("GONOW!"));

但是我很难过如何将它连接到我正在测试的实际控制器上。为了让它实际调用mocked方法,我该怎么做?

2 个答案:

答案 0 :(得分:1)

您可以为参考创建模拟,或者如果它只是代码显示的简单参考,则发送变量。然后可以调用和测试正常的模拟调用。

$ReferenceVariable= 'empty';

$mock = $this->getMock('Hello ', array('doSomething'));
$stub->expects($this->any())
     ->method('discoverRoute2')
     ->will($this->returnValue("GONOW!"));

$this->assertEquals('GONOW!', $stub->doSomething($ReferenceVariable, 'TextParameter'));

答案 1 :(得分:1)

您的示例代码无法正确解释您的问题。

您的方法允许两个参数,第一个作为参考传递。但是您为这两个参数创建了两个对象。无论函数的声明是什么,对象总是作为参考传递。

我建议不要声明一个参数作为引用传递,除非有正当理由这样做。如果您希望参数是某个对象,请添加一个typehint。如果它不能是一个对象,尽量避免将它作为引用变量传递(这将导致混乱,特别是如果你明确地传递一个对象作为参考,因为每个人都会试图找出你为什么这样做)。 p>

但你真正的问题是:

  

但是我很难过如何将它连接到我正在测试的实际控制器上。为了让它实际调用mocked方法,我该怎么做?

答案是:不要使用new Hello直接在控制器中创建对象。您必须将应该使用的对象传递给该控制器。这个对象要么是真实的,要么是测试中的模拟对象。

实现这一目标的方法称为“依赖注入”或“控制反转”。应该在任何搜索引擎中找到这意味着什么的解释。

简而言之:将要使用的对象传递给另一个对象,而不是在其中创建它。您可以使用构造函数接受对象作为参数,或者该方法可以允许一个额外的参数本身。您还可以编写一个setter函数(可选)被调用并用新实例替换常用的默认对象。