Он Алекс,
Я говорил с Себастьяном (создателем phpunit) об этой проблеме, и да: Аргумент получает clone
ed, прежде чем он будет передан обратному вызову.
ИзВверху головы, я не могу предложить вам никакого обходного пути, но я все равно хочу ответить, чтобы, по крайней мере, сказать вам, что вы не делаете ничего плохого и что это ожидаемое поведение.
Цитируя Себастьян, прокомментируйте IRC, почемуон клонирует аргумент:
Это долгий спор между мной, мной и пользователями PHP: не так ли это правильно; -)
Иметь что-тоcopy / pasteable:
Утверждение 3 в этом примере кода не удастся.(Переменная изменяется только в возвращенном объекте)
<?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);
}
}
Обновление:
Начиная с PHPUnit 3.7, клонирование можно отключить.См последний аргумент выключен:
public function getMock(
$originalClassName,
$methods = array(),
array $arguments = array(),
$mockClassName = '',
$callOriginalConstructor = TRUE,
$callOriginalClone = TRUE,
$callAutoload = TRUE,
$cloneArguments = FALSE
);
Возможно, он даже отключен по умолчанию:)