本文介绍了在PHPUnit Mocks的returnCallback()中修改对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想模拟一个类的方法并执行一个回调,该回调修改作为参数给定的对象(使用PHP 5.3和PHPUnit 3.5.5).

I want to mock a method of a class and execute a callback which modifies the object given as parameter (using PHP 5.3 with PHPUnit 3.5.5).

假设我有以下课程:

class A
{
  function foobar($object)
  {
    doSomething();
  }
}

此设置代码:

$mock = $this->getMockBuilder('A')->getMock();
$mock->expects($this->any())->method('foobar')->will(
  $this->returnCallback(function($object) {
    $object->property = something;
  }));

由于某种原因,对象没有被修改.在var_dump ing $object上,我看到它是正确的对象.可能是对象被值传递了吗?如何配置模拟接收参考?

For some reason the object does not get modified. On var_dumping $object I see it is the right object. Could it be that the object gets passed by value? How can I configure the mock to receive a reference?

推荐答案

亚历克斯,

我与Sebastian(phpunit创建者)讨论了这个问题,是的:在传递给回调之前,该参数先被clone ed.

i talked to Sebastian (the phpunit creator) about that problem and yes: The argument gets cloneed before it is passed to the callback.

从头开始,我无法为您提供任何解决方法,但是我还是选择回答,至少告诉您您没有做错任何事情,这是预期的行为.

From the top of my head i can't offer you any workaround but i choose to answer anyway to at least tell you that you are doing nothing wrong and that this is expected behavior.

引用塞巴斯蒂安(Sebastians)关于IRC为何会克隆参数的评论:

To quote Sebastians comment on IRC on why it clones the argument:

要复制/粘贴内容:

此代码示例中的断言3将失败. (仅在返回的对象中更改变量)

Assertion 3 in this codesample will fail. (The variable is only changed in the returned object)

<?php
class A
{
    function foobar($o)
    {
        $o->x = mt_rand(5, 100);
    }
}

class Test extends PHPUnit_Framework_TestCase
{
    public function testFoo()
    {
        $mock = $this->getMock('A');
        $mock->expects($this->any())
             ->method('foobar')
             ->will($this->returnCallback(function($o) { $o->x = 2; return $o; }));

        $o = new StdClass;
        $o->x = 1;

        $this->assertEquals(1, $o->x);
        $return = $mock->foobar($o);

        $this->assertEquals(2, $return->x);
        $this->assertEquals(2, $o->x);
    }
}


更新:


Update:

从PHPUnit 3.7开始,可以关闭克隆.请关闭最后一个参数:

Starting with PHPUnit 3.7 the cloning can be turned off. See the last argument off:

public function getMock(
    $originalClassName,
    $methods = array(),
    array $arguments = array(),
    $mockClassName = '',
    $callOriginalConstructor = TRUE,
    $callOriginalClone = TRUE,
    $callAutoload = TRUE,
    $cloneArguments = FALSE
);

默认情况下它甚至可能处于关闭状态:)

It might even be off by default :)

这篇关于在PHPUnit Mocks的returnCallback()中修改对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-01 18:17