PHPSPEC - метод возвращает объект вместо строки
Вопрос
Я все еще свежую в phpspec, но обычно я нахожу решение, когда я борюсь с чем-то, но этот жесткий.
Я пробовал много разных подходов, и я не нашел решение.Я использую symfony2.
У меня есть класс, который я хочу проверить:
class MyClass
{
public function getDataForChildren(MyObject $object)
{
foreach ($object->getChildren() as $child) {
$query = \json_decode($child->getJsonQuery(), true);
$data = $this->someFetcher->getData($query);
$child->setData($data);
}
return $object;
}
}
.
И вот как посмотреть мой спецификационный класс:
class MyClassSpec
{
function let(SomeFetcher $someFetcher)
{
$this->beConstructedWith($someFetcher);
}
function it_is_initializable()
{
$this->shouldHaveType('MyClass');
}
function it_should_get_data_for_children_and_return_object(
MyClass $object,
MyClass $child, // it means that MyClass has a self-reference to MyClass
$someFetcher
)
{
$query = '{"id":1}';
$returnCollection = new ArrayCollection(array($child));
$object->getChildren()->shouldBeCalled()->willReturn($returnCollection);
$child->getJsonQuery()->shouldBeCalled()->willReturn($query);
$someFetcher->getData($query)->shouldBeCalled();
$this->getDataForChildren($object);
}
}
.
и после запуска phpspec я получаю эту ошибку:
warning: json_decode() expects parameter 1 to be string, object given in
.
Я понятия не имею, как решить эту проблему.Если у кого-то есть ключ, пожалуйста, помогите.
Решение
Это обычный камень блок с phpspec, декларацией:
MyClass $child
.
означает, что объект Collaborator of $ Child будет настроен с тем же интерфейсом MyClass. Когда Child-> getjsonquery () вызывается в SUT (класс, вы тестируете), он вернет A MethodProphecy , а не строку, которую вы ожидаете, чтобы вернуться.
То, что вы хотите сказать, это то, что ваша ArrayCollection будет содержать себя не $ Child Mids (который является объектом Collaborator), но реальный объект, который коллаборатор обернулся. Вы делаете это так:
$returnCollection = new ArrayCollection(array($child->getWrappedObject()));
.
Кроме того, вы не должны использовать (то есть лишнее) оба Doctballed () и WillReturn () на одном сотрудничестве, один или другой достаточно. Если вы указали, что будет Collabrator Вернитесь, ясно, что он будет называться с сатом. Должен быть использован () должен использоваться в «Assert» части теста в Чтобы подтвердить, что сотрудник был вызван с ожидаемым аргументы или в нужное время.
Ваш последний SUT и SPEC должен выглядеть что-то подобное:
class MyClass
{
/**
* @var SomeFetcher
*/
private $someFetcher;
public function getDataForChildren(MyObject $object)
{
foreach ($object->getChildren() as $child) {
$query = \json_decode($child->getJsonQuery(), true);
$data = $this->someFetcher->getData($query);
$child->setData($data);
}
return $object;
}
public function getJsonQuery()
{
}
public function setData()
{
}
public function __construct(SomeFetcher $someFetcher)
{
$this->someFetcher = $someFetcher;
}
}
.
class MyClassSpec extends ObjectBehavior
{
function let(SomeFetcher $someFetcher)
{
$this->beConstructedWith($someFetcher);
}
function it_should_get_data_for_children_and_return_object(
MyObject $object,
MyClass $child, // it means that MyClass has a self-reference to MyClass
SomeFetcher $someFetcher
)
{
$query = '{"id":1}';
$returnCollection = new ArrayCollection(array($child->getWrappedObject()));
$object->getChildren()->willReturn($returnCollection);
$child->getJsonQuery()->willReturn($query);
$child->setData(Argument::any())->shouldBeCalled();
$someFetcher->getData(array('id' => 1))->shouldBeCalled();
$this->getDataForChildren($object);
}
}
.
также, линия
$query = \json_decode($child->getJsonQuery(), true);
.
создаст ассоциированный массив в $ Query, т. Е. Массив ('id'=> 1) (это то, что устанавливает второй «истинный» аргумент на JSON_ENCODE), поэтому вы ожидаете, что $ quotefetcher-> getData () Как называться с последним, следовательно:
$someFetcher->getData(array('id' => 1))->shouldBeCalled();
.