Возврат PHPUnitValueMap не дает ожидаемых результатов


Answers

Я искал эту же проблему и, в конечном счете, из отчаяния xdebug, шаг за шагом через Framework / MockObject / Stub / ReturnValueMap.php и Framework / MockObject / InvocationMocker.php [в методе InvocationMocker :: invoke (PHPUnit_Framework_MockObject_Invocation $ invocation)] и Я заметил следующие моменты:

  1. Мало того, что значения в массиве map, которые вы поставляете, будут такими же, как ожидаемые параметры при вызове функции-заглушки, но они ДОЛЖНЫ БЫТЬ ОДНОГО ТИПА. Это связано с тем, что внутри Framework / MockObject / Stub / ReturnValueMap.php в методе ReturnValueMap :: invoke () сравнение между параметрами и ожидаемыми параметрами сравнивается по строке 75 следующим образом:

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

    Итак, ожидаемый результат

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

    используя карту-массив

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

    разочарует. Вместо этого результатом будет NULL.

  2. В гораздо более тонкой точке вы могли бы опустить метод, используя два разных сценария (как и я - да, глупый!)

    Итак, чтобы выяснить, первый макет-заглушка может содержать

    $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-method, будет реализована версия массива карт. Это очевидно и само собой разумеется, однако при кодировании в разгар моментов и при раздельном разном кодовом поведении в вашем сознании, когда вы развиваетесь, его легко упускать из виду.

Question

Я пытаюсь использовать returnValueMap() для PHPUnit для returnValueMap() результатов чтения. Это не дает ожидаемых результатов, но эквивалент returnCallback (). Я сделал свой тестовый кейс доступным, если вы хотите осмотреть его самостоятельно.

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"

Предприятие :: подписаться

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

Почему не возвращает функциюValueMap (), как я ожидаю? Что именно мне не хватает?




Related