Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get PHPUnit MockObjects to return different values based on a parameter?

I've got a PHPUnit mock object that returns 'return value' no matter what its arguments:

// From inside a test... $mock = $this->getMock('myObject', 'methodToMock'); $mock->expects($this->any))      ->method('methodToMock')      ->will($this->returnValue('return value')); 

What I want to be able to do is return a different value based on the arguments passed to the mock method. I've tried something like:

$mock = $this->getMock('myObject', 'methodToMock');  // methodToMock('one') $mock->expects($this->any))      ->method('methodToMock')      ->with($this->equalTo('one'))      ->will($this->returnValue('method called with argument "one"'));  // methodToMock('two') $mock->expects($this->any))      ->method('methodToMock')      ->with($this->equalTo('two'))      ->will($this->returnValue('method called with argument "two"')); 

But this causes PHPUnit to complain if the mock isn't called with the argument 'two', so I assume that the definition of methodToMock('two') overwrites the definition of the first.

So my question is: Is there any way to get a PHPUnit mock object to return a different value based on its arguments? And if so, how?

like image 782
Ben Dowling Avatar asked Nov 10 '08 13:11

Ben Dowling


2 Answers

Use a callback. e.g. (straight from PHPUnit documentation):

<?php class StubTest extends PHPUnit_Framework_TestCase {     public function testReturnCallbackStub()     {         $stub = $this->getMock(           'SomeClass', array('doSomething')         );          $stub->expects($this->any())              ->method('doSomething')              ->will($this->returnCallback('callback'));          // $stub->doSomething() returns callback(...)     } }  function callback() {     $args = func_get_args();     // ... } ?> 

Do whatever processing you want in the callback() and return the result based on your $args as appropriate.

like image 58
Howard Sandford Avatar answered Sep 17 '22 19:09

Howard Sandford


From the latest phpUnit docs: "Sometimes a stubbed method should return different values depending on a predefined list of arguments. You can use returnValueMap() to create a map that associates arguments with corresponding return values."

$mock->expects($this->any())     ->method('getConfigValue')     ->will(         $this->returnValueMap(             array(                 array('firstparam', 'secondparam', 'retval'),                 array('modes', 'foo', array('Array', 'of', 'modes'))             )         )     ); 
like image 38
Nikola Ivancevic Avatar answered Sep 17 '22 19:09

Nikola Ivancevic