ReturnValueMap PHPUnit не дает ожидаемых результатов
Я пытаюсь использовать 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"
Enterprise:: подписаться
public function subscribe() {
echo 'Subscription ID: ';
var_dump($this->field('subscription_id'));
echo 'Name: ';
var_dump($this->field('name'));
}
почему returnValueMap () не работает так, как я ожидаю? Что именно я упускаю?
3 ответов
у меня была такая же проблема, и в конце концов я узнал, что 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))));
без null в середине он не будет работать.
я охотился за этой же проблемой и в конечном итоге из отчаяния xdebug-шагнул через Framework/MockObject/Stub/ReturnValueMap.php и Framework/MockObject / InvocationMocker.php [в методе InvocationMocker:: invoke (PHPUnit_Framework_MockObject_Invocation $invocation)], и я заметил следующие моменты:
-
не только значения в массиве карт, который вы предоставляете, должны совпадать с ожидаемыми параметрами, когда функция stubbed звонили, но они должны быть одного типа. Это связано с тем, что внутри Framework/MockObject/Stub / ReturnValueMap.php в методе ReturnValueMap:: invoke () сравнение между предоставленными параметрами и ожидаемыми параметрами сравнивается в строке 75 следующим образом:
if ($invocation->parameters === $map) {
Итак, ожидаемый результат
$mock->myStubbedMethod( "1", "2" )
использование map-массива
array( array( 1, 1, 500 ), array( 1, 2, 700 ) )
разочарует. Вместо этого результатом будет значение NULL.
-
на гораздо более тонкий момент, Вы, возможно, заглушили метод, используя два разных макетных сценария (как и я - да, глупый я!)
Итак, чтобы прояснить, первый макет-заглушка может содержать
$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-будет реализована версия массива карт. Это очевидно и самоочевидно, однако при кодировании в пылу момента и при разделении другого кода поведение в вашем уме, когда вы развиваетесь, легко упускается из виду.
проблема, похоже, лежит где-то еще в коде или может быть проблемой со старой версией 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)
поэтому, хотя я не могу сказать, почему это не работает, я могу, по крайней мере, сказать вам, что вы делаете это правильно и что вы поняли returnValueMap
правильно :)