PHPUnit存根:映射的默认返回值

PHPUnit存根:映射的默认返回值,php,phpunit,stub,Php,Phpunit,Stub,我在PHPUnit手册中读到,在下面的示例中,方法调用doSomething('a','b','c')将返回d,方法调用doSomething('e','f','g')将返回h <?php require_once 'SomeClass.php'; class StubTest extends PHPUnit_Framework_TestCase { public function testReturnValueMapStub() { // Create

我在PHPUnit手册中读到,在下面的示例中,方法调用
doSomething('a','b','c')
将返回
d
,方法调用
doSomething('e','f','g')
将返回
h

<?php
require_once 'SomeClass.php';

class StubTest extends PHPUnit_Framework_TestCase
{
    public function testReturnValueMapStub()
    {
        // Create a stub for the SomeClass class.
        $stub = $this->getMockBuilder('SomeClass')
                     ->getMock();

        // Create a map of arguments to return values.
        $map = array(
          array('a', 'b', 'c', 'd'),
          array('e', 'f', 'g', 'h')
        );

        // Configure the stub.
        $stub->method('doSomething')
             ->will($this->returnValueMap($map));

        // $stub->doSomething() returns different values depending on
        // the provided arguments.
        $this->assertEquals('d', $stub->doSomething('a', 'b', 'c'));
        $this->assertEquals('h', $stub->doSomething('e', 'f', 'g'));
    } 
}
?>


是否还有一种方法可以定义这样的返回值映射,但在特定输入参数没有特定返回值时使用默认返回值?

您可以使用returnCallback而不是returnValueMap,并重现值映射所做的操作:

<?php
require_once 'SomeClass.php';

class StubTest extends PHPUnit_Framework_TestCase
{
    public function testReturnValueMapStub()
    {
        // Create a stub for the SomeClass class.
        $stub = $this->getMockBuilder( 'SomeClass' )
            ->getMock();

        // Create a map of arguments to return values.
        $valueMap = array(
            array( 'a', 'b', 'c', 'd' ),
            array( 'e', 'f', 'g', 'h' )
        );

        $default = 'l';

        // Configure the stub.
        $stub->method( 'doSomething' )
            ->will( $this->returnCallback( function () use ( $valueMap, $default )
            {
                $arguments      = func_get_args();
                $parameterCount = count( $arguments );

                foreach( $valueMap as $map )
                {
                    if( !is_array( $map ) || $parameterCount != count( $map ) - 1 )
                    {
                        continue;
                    }

                    $return = array_pop( $map );
                    if( $arguments === $map )
                    {
                        return $return;
                    }
                }

                return $default;
            } ) );


        // $stub->doSomething() returns different values depending on
        // the provided arguments.
        $this->assertEquals( 'd', $stub->doSomething( 'a', 'b', 'c' ) );  
        $this->assertEquals( 'h', $stub->doSomething( 'e', 'f', 'g' ) );
        $this->assertEquals( 'l', $stub->doSomething( 'i', 'j', 'k' ) );
        $this->assertEquals( 'l', $stub->doSomething( 'any', 'arguments', 'at', 'all' ) );
    }
}

规则

  • $map
    变量的firts数组参数必须是测试方法的参数,其余(在本例中为
    $f
    )是可能返回测试方法的期望值
  • $map
    变量中的每个
    array()
    都必须在不同的调用上进行尝试:

    //firts$map的元素变量
    $this->assertEquals($f),$project->getSupervisorfromUnits($r));
    //第二个$map的元素变量
    $this->assertEquals($s),$project->getSupervisorfromUnits($r))

  • 另外,
    executes()
    方法必须是调用数

     /**
     * @test
     */
    public function testReturnValueMapStub()
    {
        $f = new Response;
        $r = new Request;
        $s = 'lol';
    
        $project = $this->getMockBuilder('AppBundle\Controller\ProjectController')
                     ->getMock();
    
        // Create a map of arguments to return values.
        $map = array(
            array($r,$f),
            array($r,$s)
        );
    
        $project->expects($this->exactly(2))
                ->method('getProjects')
                ->will($this->returnValueMap($map));
    
        $this->assertEquals("$f",$project->getProjects($r));
        $this->assertEquals("$s",$project->getProjects($r)); // will fail the assertion
    
    }