Die returnValueMap von PHPUnit liefert keine erwarteten Ergebnisse


Answers

Ich habe dieses selbe Problem aufgespürt und bin aus Verzweiflung xdebug-step durch Framework / MockObject / Stub / ReturnValueMap.php und Framework / MockObject / InvocationMocker.php [in der Methode InvocationMocker :: invoke (PHPUnit_Framework_MockObject_Invocation $ invocation)] und Ich habe die folgenden Punkte beobachtet:

  1. Nicht nur müssen die Werte im map-Array, die Sie angeben, mit den erwarteten Parametern übereinstimmen, wenn die Stubbed-Funktion aufgerufen wird, sondern MÜSSEN DEN GLEICHEN TYP aufweisen. Dies liegt daran, dass innerhalb von Framework / MockObject / Stub / ReturnValueMap.php in der ReturnValueMap :: invoke () -Methode der Vergleich zwischen den bereitgestellten 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" )

    mit einem Karten-Array von

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

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

  2. An einem viel subtileren Punkt haben Sie vielleicht die Methode mit zwei verschiedenen Schein-Szenarien gestuppt (wie ich es tat - ja, dumm!)

    Also, um zu erklären, könnte der erste Mock-Stub enthalten

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

    und dann 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 Moments kodieren und während Sie unterschiedliche Code-Verhalten in Ihrem Geist trennen, wird es leicht übersehen.

Question

Ich versuche, PHPUnits returnValueMap () zu verwenden, um die Ergebnisse eines Lesens auszudrücken . Es liefert nicht die erwarteten Ergebnisse, aber ein äquivalentes returnCallback () tut es. Ich habe meinen Testfall zur Verfügung gestellt, wenn Sie ihn selbst überprüfen 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"

Enterprise :: abonnieren

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

Warum funktioniert returnValueMap () nicht wie erwartet? Was genau vermisse ich?