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

227

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?

818

Answer

Solution:

You can also simplify these statements a bit. If all you're needing to do is mock the function so that when you pass 'param1' you get back 'test1', then this should work:

$mock->method('myMethod')
    ->with('param1')
    ->willReturn('test1');

$mock->method('myMethod')
    ->with('param2')
    ->willReturn('test2');
63

Answer

Solution:

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 argparam1 then$mock->myMethod('param1') and will returntest1, second - with argparam2 and will returntest2.

People are also looking for solutions to the problem: php - display data from database based on other column table laravel 5

Source

Didn't find the answer?

Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.

Ask a Question

Write quick answer

Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.

Similar questions

Find the answer in similar questions on our website.