在PHPUnit中进行模拟时,在回调中通过引用传递

时间:2011-03-02 16:57:24

标签: php unit-testing phpunit

我有一个我想要模拟的界面,并模仿其中一个方法的行为。

所以我创建了一个非常简单地模仿行为的回调。

如果我创建一个基于此接口的新对象,则会通过此测试,但我想模拟该接口。

模拟的setUp方法被称为正常,并且在我的回调中调用getVar('testing')返回值。但是我的断言失败了,因为这个值不可用。

似乎你不能在PHPUnit中这样做?除非我是愚蠢的。

代码流程的简要说明; “getVar”中的代码调用一个方法,该方法在添加的插件上调用“setUp”。当它调用“setUp”时,它会传入“$ this”。这是$ this我希望通过引用传递,并使用“真实”对象。

class DefaultRendererTest extends \PHPUnit_Framework_TestCase
{

    public function testSetGetVar()
    {
        $theme = $this->getMock('ThemeInterface');

        $plugin = $this->getMock('PluginInterface');
        $plugin->expects($this->once())
          ->method('setUp')
          ->will($this->returnCallback(function($r){

              $r->setVar('testing', "fooBar");

        }));

        $renderer = new DefaultRenderer($theme, null);
        $renderer->addPlugin($plugin);
        $this->assertEquals('fooBar',$renderer->getVar('testing'));
    }
}

这里的信息是接口,DefaultRenderer实现了RendererInterface

interface PluginInterface
{
    function setUp(RendererInterface $renderer);
}

1 个答案:

答案 0 :(得分:4)

好的,出于兴趣,我追查了这个问题。似乎PHPUnit会在实际调用发生之前自动克隆参数。我没有看到这个的真正原因,但也许有一个。看一下Framework/MockObject/Invocation/Static.php,只有一种方法可以避免这种情况(基于内置的模拟代码):在__clone()中实现私有DefaultRenderer方法。 / p>

我还建议您在IRC或PHPUnit邮件列表上询问此行为或模拟对象库。