2012-10-05 108 views
29

PHPUnitのreturnValueMap()を使用して、読み込み結果をスタブしてみようとしています。期待される結果が得られていませんが、同等のreturnCallback()はそれを行います。自分で調べたいのであればtest caseを利用可能にしました。PHPUnitのreturnValueMapが期待どおりの結果を出さない

returnValueMap()

$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'); 

結果:

Subscription ID: NULL 
Name: NULL 

returnCallback()

$enterprise = $this->getMock('Enterprise', array('field')); 
$enterprise->expects($this->any()) 
    ->method('field') 
    ->will($this->returnCallback(function ($arg) { 
     $map = array(
      'subscription_id' => null, 
      'name' => 'Monday Farms' 
     ); 
     return $map[$arg]; 
    })); 
$enterprise->subscribe('basic'); 

結果:

私はそれを期待するよう
Subscription ID: NULL 
Name: string(12) "Monday Farms" 

エンタープライズ::なぜ(returnValueMapしない

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

をサブスクライブ)は動作しますか?私は何が欠けているのですか?

答えて

82

私は同じ問題を抱えていましたが、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)))); 

途中でヌルがなければ、それは動作しません。

+0

あなたは私の一日を保存しました!ありがとう! – haltabush

+9

あなたはただ私を救っただけです**たくさんの頭痛。ありがとう。 PS:PHPUnitの多くの不具合は、公式の文書に含まれていないことは残念です。 –

+0

ライフセーバー! '$ param'(キー)が整数である場合には、' null'が 'false'である必要がある場合もあります – esh

0

問題はコードのどこかにあるか、古いPHPUnitバージョンの問題かもしれません。

私にとっては、このコードを使用して動作します。

猫EnterpriseTest.php

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

} 

出力:

phpunit-dev EnterpriseTest.php 
PHPUnit 3.7.6 by Sebastian Bergmann. 

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


Time: 0 seconds, Memory: 6.75Mb 

OK (1 test, 1 assertion) 

だから、それはdoesnのなぜ私が言うことができない一方、私はあなたがそれを正しくやっていること、そしてあなたが理解していることを少なくとも伝えることができますreturnValueMap c orrectly :)

8

私はこの同じ問題を捜し求めていましたが、最終的にはxdebug-Framework/MockObject/Stub/ReturnValueMap.phpとFramework/MockObject/InvocationMockerを使いました。ユーザーが指定するマップ配列の値が予想と同じでなければなりません

  1. だけでなく、:[メソッドのInvocationMockerで::(PHPUnit_Framework_MockObject_Invocation $呼び出し)を呼び出す] PHP、およびIは、以下の点を観察してきましたスタブされた関数が呼び出されたときのパラメータですが、同じ型でなければなりません。 、

    だから
    if ($invocation->parameters === $map) { 
    

    :これは、フレームワーク/ MockObject /スタブ/ ReturnValueMap.php内部ReturnValueMapに::呼び出す()メソッドは、次のように指定されたパラメータと期待されるパラメータとの比較をライン75で比較され

    array(
        array(1, 1, 500), 
        array(1, 2, 700) 
    ) 
    

    のマップアレイを用い

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

    の予想結果は失望します。代わりに、結果はNULLになります。はるかに微妙な点については

  2. (私が行ったように! - 私ははい、愚かな)、あなたは二つの異なる模擬シナリオを用いた方法をスタブ化している可能性があり

    をので、解明し、最初のモックスタブが含まれている可能性があり

    $mock->expects($this->any()) 
         ->method('myStubbedMethod') 
         ->will($this->returnValue(750)); 
    

    そしてその後、同じユニットテスト方法では、スタブ・メソッドが呼び出されると、地図アレイバージョンがIMなり

    $arrMap = array(
        array(1, 1, 500), 
        array(1, 2, 700), 
        array(2, 3, 1500), 
    ); 
    $mock->expects($this->any()) 
         ->method('myStubbedMethod') 
         ->will($this->returnValueMap($arrMap)); 
    

    を含めることができplemented。これは明白で自明ですが、瞬間の暑さでコーディングしながら、開発中に異なるコードの振る舞いを分離しながら、簡単に見落とされます。

関連する問題