miszmaniac
miszmaniac

Reputation: 895

PHPUnit willReturnMap method - callback argument

My use case is more complex, but to keep it simple:

class MockObject {
    public function test($param1, callable $callback = null) {
        return is_null($callback) ? $param1 : $callback($param1);
    }
}

I would like to mock this class for my other tests using returnMap.

$map = [
    ['a', null, 'a'],
    ['b', $WHAT_SHOULD_BE_HERE?, 'b']
];

$mock = $this->getMock('MockObject');
$mock->expects($this->atLeastOnce())->method('test')->willReturnMap($map);

$this->assertEquals('a', $mock->test('a')); // Works 
$this->assertEquals('b', $mock->test('b', function($value){return $value})); // Doesn't work 

Upvotes: 4

Views: 18720

Answers (1)

gontrollez
gontrollez

Reputation: 6548

Just define a $callback and use it in the map and the assertion:

$callback = function($value) { return $value; };

$map = [
    ['a', null, 'a'],
    ['b', $callback, 'b']
];

$mock = $this->getMock('MockObject');
$mock->expects($this->atLeastOnce())->method('test')->will($this->returnValueMap($map));

$this->assertEquals('a', $mock->test('a')); // Works 
$this->assertEquals('b', $mock->test('b', $callback)); // Should work

You can take more control of all the cases by using a function for computing the return value:

$mock = $this->getMock('MockObject');
$mock->expects($this->atLeastOnce())
     ->method('test')
     ->will($this->returnCallback(function($param1, $param2) {
          // return value depends on parameters
     }));    

Upvotes: 8

Related Questions