Jacob Cohen Jacob Cohen - 2 months ago 6
PHP Question

PHPUnit how to test a specific method with specific parameter with specific answer for more than one call

I have tried testing multiple parameters for a specific method, and get different answers by the same mock for different parameters.

This is what I've done so far:

$mock = $this->getMockBuilder('MyClass')->disableOriginalConstructor()->getMock();

$mock->expects($this->any())
->method('myMethod')
->with($this->equalTo('param1'))
->will($this->returnValue('test1'));
$mock->expects($this->any())
->method('myMethod')
->with($this->equalTo('param2'))
->will($this->returnValue('test2'));


When I call
$myClass->myMethod('param1')
all is well and I get the
'test1'


However, here's the problem:

When I call
$myClass->myMethod('param2')
I get an error


Failed asserting that two strings are equal.
--- Expected
+++ Actual @@ @@
-'param1'
+'param2'


A solution I have found is to just create a new mock for each call.

$mock1 = $this->getMockBuilder('MyClass')->disableOriginalConstructor()->getMock();
$mock1->expects($this->any())
->method('myMethod')
->with($this->equalTo('param1'))
->will($this->returnValue('test1'));

$mock2 = $this->getMockBuilder('MyClass')->disableOriginalConstructor()->getMock();
$mock2->expects($this->any())
->method('myMethod')
->with($this->equalTo('param2'))
->will($this->returnValue('test2'));


I do not know though why is this needed, perhaps I am using it wrong.

So the question remains:

How do I mock the same class, with a specific method, for different parameters and get different return values?

Answer

If it's about dependency for a tested class, that is called twice inside tested method then it could be made like this

$mock = $this->getMockBuilder('MyClass')->disableOriginalConstructor()->getMock();

$mock->expects($this->at(0))
            ->method('myMethod')
            ->with($this->equalTo('param1'))
            ->will($this->returnValue('test1'));
$mock->expects($this->at(1))
            ->method('myMethod')
            ->with($this->equalTo('param2'))
            ->will($this->returnValue('test2'));

The first time it must be called with arg param1 then $mock->myMethod('param1') and will return test1, second - with arg param2 and will return test2.

Comments