Die returnValueMap von PHPUnit liefert keine erwarteten Ergebnisse



Answers

Ich habe dieses gleiche Problem und schließlich aus Verzweiflung xdebug-gestuft durch Framework / MockObject / Stub / ReturnValueMap.php und Framework / MockObject / InvocationMocker.php [in der Methode InvocationMocker :: invoke (PHPUnit_Framework_MockObject_Invocation $ Aufruf)], und Ich habe die folgenden Punkte beobachtet:

  1. Die Werte in dem von Ihnen angegebenen map-array müssen nicht nur den erwarteten Parametern entsprechen, wenn die stubbed-Funktion aufgerufen wird, sondern MÜSSEN GLEICHER TYPE sein. Dies liegt daran, dass innerhalb von Framework / MockObject / Stub / ReturnValueMap.php in der ReturnValueMap :: invoke () -Methode der Vergleich zwischen den angegebenen Parametern und den erwarteten Parametern in Zeile 75 wie folgt verglichen wird:

    if ($invocation->parameters === $map) {
    

    Also, das erwartete Ergebnis von

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

    Verwenden eines Karten-Arrays von

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

    wird enttäuschen. Stattdessen wird das Ergebnis ein NULL sein.

  2. An einem wesentlich subtileren Punkt haben Sie vielleicht die Methode mit zwei verschiedenen Szenarios gestempelt (wie ich es tat - ja, ich Dummkopf!)

    Um das zu erklären, könnte der erste Schein-Stub enthalten

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

    und später, in der gleichen Unit-Test-Methode, könnte es enthalten

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

    Wenn die Stubbed-Methode aufgerufen wird, wird die Map-Array-Version implementiert. Dies ist offensichtlich und selbstverständlich, aber während Sie in der Hitze des Augenblicks kodieren, und während Sie sich entwickeln, wird das unterschiedliche Code-Verhalten in Ihrem Geist voneinander getrennt.

Question

Ich versuche, PHPUnit's returnValueMap() zu verwenden, um die Ergebnisse eines returnValueMap() . Es liefert nicht die erwarteten Ergebnisse, aber eine äquivalente returnCallback () tut. Ich habe meinen Testfall zur Verfügung gestellt, wenn Sie ihn selbst untersuchen möchten.

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

Ergebnisse:

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

Ergebnisse:

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

Unternehmen :: abonnieren

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

Warum funktioniert returnValueMap () nicht so, wie ich es erwarte? Was genau vermisse ich?






Links