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

前端 未结 11 1585
忘掉有多难
忘掉有多难 2020-12-04 05:43

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

// From inside a test...
$mock = $this->getMock(\         


        
相关标签:
11条回答
  • 2020-12-04 06:19
    $this->BusinessMock = $this->createMock('AppBundle\Entity\Business');
    
        public function testBusiness()
        {
            /*
                onConcecutiveCalls : Whether you want that the Stub returns differents values when it will be called .
            */
            $this->BusinessMock ->method('getEmployees')
                                    ->will($this->onConsecutiveCalls(
                                                $this->returnArgument(0),
                                                $this->returnValue('employee')                                      
                                                )
                                          );
            // first call
    
            $this->assertInstanceOf( //$this->returnArgument(0),
                    'argument',
                    $this->BusinessMock->getEmployees()
                    );
           // second call
    
    
            $this->assertEquals('employee',$this->BusinessMock->getEmployees()) 
          //$this->returnValue('employee'),
    
    
        }
    
    0 讨论(0)
  • 2020-12-04 06:21

    It is not exactly what you ask, but in some cases it can help:

    $mock->expects( $this->any() ) )
     ->method( 'methodToMock' )
     ->will( $this->onConsecutiveCalls( 'one', 'two' ) );
    

    onConsecutiveCalls - returns a list of values in the specified order

    0 讨论(0)
  • 2020-12-04 06:22

    I had a similar problem (although slightly different... I didn't need different return value based on arguments, but had to test to ensure 2 sets of arguments were being passed to the same function). I stumbled upon using something like this:

    $mock = $this->getMock();
    $mock->expects($this->at(0))
        ->method('foo')
        ->with(...)
        ->will($this->returnValue(...));
    
    $mock->expects($this->at(1))
        ->method('foo')
        ->with(...)
        ->will($this->returnValue(...));
    

    It's not perfect, since it requires that the order of the 2 calls to foo() is known, but in practice this probably isn't too bad.

    0 讨论(0)
  • 2020-12-04 06:22

    Pass two level array, where each element is an array of:

    • first are method parameters, and least is return value.

    example:

    ->willReturnMap([
        ['firstArg', 'secondArg', 'returnValue']
    ])
    
    0 讨论(0)
  • 2020-12-04 06:23

    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'))
                )
            )
        );
    
    0 讨论(0)
  • 2020-12-04 06:25

    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.

    0 讨论(0)
提交回复
热议问题