【问题标题】:PHPUnit mock a controller with reference parameter?PHPUnit用参考参数模拟控制器?
【发布时间】:2014-03-18 05:01:30
【问题描述】:

我有一堂课:

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'));

然后加上return:

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

但我不知道如何将它连接到我正在测试的实际控制器。我需要做什么才能让它真正调用模拟方法?

【问题讨论】:

    标签: zend-framework mocking phpunit


    【解决方案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'));
    

    【讨论】:

      【解决方案2】:

      您的示例代码没有正确解释您的问题。

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

      我建议不要声明要作为引用传递的参数,除非有正当理由这样做。如果您希望参数是某个对象,请添加类型提示。如果它一定不是对象,请尽量避免将其作为引用变量传递(这无论如何都会导致混淆,特别是如果你明确地将对象作为引用传递,因为每个人都会试图弄清楚你为什么这样做)。

      但你真正的问题是:

      但我不知道如何将它连接到我正在测试的实际控制器。我需要做什么才能让它真正调用模拟方法?

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

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

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

      【讨论】:

        猜你喜欢
        • 2013-04-24
        • 1970-01-01
        • 1970-01-01
        • 2012-10-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-21
        • 1970-01-01
        相关资源
        最近更新 更多