Reputation: 6197
Class Testme
{
public function testMe ($input, &$output)
{
$output = 9;
}
}
as you all can see, this method modifies an input parameter. Now how to mock it? Something like mocking the return value
$mock = $this->getMock ('Testme');
$mock = $this->expects ($this->once())->with (1, 0)->will
what to write here to modify the 2nd parameter? I want the 2nd parameter to be 10.
Upvotes: 2
Views: 2211
Reputation: 84
Unfortunately this is not possible if you use PHPUnit Mock Objects. See known issue #81 "Arguments that are passed by reference are not handled properly.
I would recommend to use Prophecy instead. Prophecy will be supported by default in PHPUnit >= 4.5. In the meanwhile you can include phpspec/prophecy-phpunit, which integrates prophecy in PHPUnit.
Here is a use case with Prophecy:
namespace SchlimmerFinger;
use Prophecy\PhpUnit\ProphecyTestCase;
class MockWithReferenceTest extends ProphecyTestCase
{
public function testShouldChangeValue()
{
$foo = $this->prophesize(__NAMESPACE__ . '\\Foo');
$a = 20;
$b = 35;
$c = 22;
$foo->bar($a, $b, $c)->will(function(array $arguments) use (&$b){
$arguments[1] = $b = 10;
return array_sum($arguments);
});
self::assertEquals(52, $foo->reveal()->bar($a, $b, $c));
self::assertEquals(10, $b);
}
}
class Foo
{
public function bar($a, &$b, $c)
{
}
}
Upvotes: 2
Reputation: 288
$mock = $this->getMock('Testme');
$mock->expects($this->once())
->method('testMe')
->with(1, 0)
->will(
$this->returnCallback(
function ($input, &$output) {
$output = 10;
}
)
);
but beware! it still wouldn't work, cause of twice calling (issue: https://github.com/sebastianbergmann/phpunit-mock-objects/issues/181)
you can work around this with this solution: https://github.com/sebastianbergmann/phpunit-mock-objects/issues/181#issuecomment-52289669
Upvotes: 2