PHPUnit';s returnValueMap未产生预期结果

PHPUnit';s returnValueMap未产生预期结果,php,cakephp,phpunit,Php,Cakephp,Phpunit,我正在尝试使用PHPUnit来删除读取的结果。它不会产生预期的结果,但等效的returnCallback()会产生预期的结果。如果你想亲自检查的话,我已经准备好了 returnValueMap() 结果: Subscription ID: NULL Name: NULL Subscription ID: NULL Name: string(12) "Monday Farms" returnCallback() 结果: Subscription ID: NULL Name: NULL Sub

我正在尝试使用PHPUnit来删除读取的结果。它不会产生预期的结果,但等效的returnCallback()会产生预期的结果。如果你想亲自检查的话,我已经准备好了

returnValueMap()

结果:

Subscription ID: NULL
Name: NULL
Subscription ID: NULL
Name: string(12) "Monday Farms"
returnCallback()

结果:

Subscription ID: NULL
Name: NULL
Subscription ID: NULL
Name: string(12) "Monday Farms"
企业::订阅

public function subscribe() {
    echo 'Subscription ID: ';
    var_dump($this->field('subscription_id'));
    echo 'Name: ';
    var_dump($this->field('name'));
}

为什么returnValueMap()不能像我期望的那样工作?我到底遗漏了什么?

问题似乎存在于代码的其他地方,或者可能是旧PHPUnit版本的问题

对我来说,它使用以下代码工作:

cat EnterpriseTest.php

$enterprise = $this->getMock('Enterprise', array('field'));
$enterprise->expects($this->any())
    ->method('field')
    ->will($this->returnValueMap(array(
        array('subscription_id', null),
        array('name', 'Monday Farms')
    )));
$enterprise->subscribe('basic');
<?php

class EnterpriseTest extends PHPUnit_Framework_TestCase {

    public function testReturnValueMap() {
        $enterprise = $this->getMock('Enterprise', array('field'));
        $enterprise->expects($this->any())
            ->method('field')
            ->will($this->returnValueMap(array(
                array('subscription_id', null),
                array('name', 'Monday Farms')
            )))
        ;
        $enterprise->subscribe('basic');        
    }

}

class Enterprise {

    public function field($name) {
    }

    public function subscribe() {
        echo 'Subscription ID: ';
        var_dump($this->field('subscription_id'));
        echo 'Name: ';
        var_dump($this->field('name'));
    }

}

因此,虽然我不知道为什么它不起作用,但我至少可以告诉你,你做得对,并且你已经正确地理解了
returnValueMap我也遇到了同样的问题,最终发现returnValueMap()必须映射函数的所有参数,包括可选参数,然后输入所需的返回值

Zend Framework中的函数示例:

public function getParam($key, $default = null)
{
    $key = (string) $key;
    if (isset($this->_params[$key])) {
        return $this->_params[$key];
    }

    return $default;
}
必须这样映射:

$request->expects($this->any())
        ->method('getParam')
        ->will($this->returnValueMap(array(array($param, null, $value))));

>中间没有空,

我一直在追查这个问题,最终摆脱了XDebug,通过了框架/MoCbObj/Stub/ReTurnEvMeAP.PHP和Frask/MoCbObj/VoCuasMoCK.PHP[in方法调用OcMOCK:::VooKe](PHPUNITIGFrimWorksMoCKObjutsPosikCuthOutoCurcOuts]我注意到以下几点:

  • 调用stubbed函数时,您提供的map数组中的值不仅必须与预期参数相同,而且必须是相同类型的。这是因为在ReturnValueMap::invoke()方法的Framework/MockObject/Stub/ReturnValueMap.php中,第75行比较了提供的参数和预期参数,如下所示:

    if ($invocation->parameters === $map) {
    
    那么,预计的结果呢,

    $mock->myStubbedMethod( "1", "2" )
    
    使用

    array(
        array( 1, 1, 500 ),
        array( 1, 2, 700 )
    )
    
    我会失望的。相反,结果将为空

  • 在更微妙的一点上,您可能使用了两种不同的模拟场景(正如我所做的-是的,我真傻!)

    因此,为了说明,第一个模拟存根可以包含

    $mock->expects( $this->any() )
           ->method('myStubbedMethod')
           ->will( $this->returnValue(750) );
    
    $arrMap = array(
        array( 1, 1, 500 ),
        array( 1, 2, 700 ),
        array( 2, 3, 1500 ),
    );
    $mock->expects( $this->any() )
            ->method('myStubbedMethod')
            ->will( $this->returnValueMap($arrMap) );
    
    然后,在相同的单元测试方法中,它可以包含

    $mock->expects( $this->any() )
           ->method('myStubbedMethod')
           ->will( $this->returnValue(750) );
    
    $arrMap = array(
        array( 1, 1, 500 ),
        array( 1, 2, 700 ),
        array( 2, 3, 1500 ),
    );
    $mock->expects( $this->any() )
            ->method('myStubbedMethod')
            ->will( $this->returnValueMap($arrMap) );
    
    调用stubbed方法时,将实现map数组版本。这是显而易见的,然而,当在最热的时刻编码时,当在开发过程中在头脑中分离不同的代码行为时,很容易被忽略


  • 你救了我一天!谢谢你帮我省去了很多麻烦。谢谢PS:PHPUnit的许多怪癖没有出现在它的官方文档中,真是太遗憾了……救生圈!还有一些情况下,
    null
    需要是
    false
    ,尤其是
    $param
    (键)是整数时