问题描述
我想模拟一个类的方法并执行一个回调,该回调修改作为参数给定的对象(使用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_dump
ing $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 clone
ed 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()中修改对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!