【问题标题】:PHPUnit stubbing: default return value from mapPHPUnit 存根:地图的默认返回值
【发布时间】:2015-06-24 14:29:48
【问题描述】:

我在 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'));
    } 
}
?>

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

【问题讨论】:

    标签: php phpunit stub


    【解决方案1】:

    您可以使用 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' ) );
        }
    }
    

    【讨论】:

      【解决方案2】:
       /**
       * @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
      
      }
      

      规则

      1. $map 变量的第一个数组参数必须是测试方法的参数,其余的(在本例中为 $f)是预期可以返回测试方法的可能性。
      2. $map 变量中的每个 array() 都必须尝试调用差异:

        // firts $map's element variable $this->assertEquals("$f",$project->getSupervisorfromUnits($r)); // second $map's element variable $this->assertEquals("$s",$project->getSupervisorfromUnits($r));

      另外,exactly() 方法必须是调用次数。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-19
        • 2021-02-09
        • 1970-01-01
        相关资源
        最近更新 更多