我在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我不知道如何解决这个问题。如果有人有线索,请帮忙。
发布于 2015-01-01 14:58:48
这是PhpSpec的一个常见的绊脚石,声明:
MyClass $child意味着将使用$child的相同接口设置MyClass的协作对象。当在SUT (您正在测试的类)中调用子->getJsonQuery()时,它将返回一个MethodProphecy,而不是您期望它返回的字符串。
您想要说的是,您的ArrayCollection将不包含$child本身(它是一个协作者对象),而是包含协作者所包装的真实对象。你这样做:
$returnCollection = new ArrayCollection(array($child->getWrappedObject()));此外,您不应该在同一个合作者上同时使用shouldBeCalled()和willReturn() (即是多余的),其中一个就足够了。如果您指定了排序规则器将返回的内容,那么很明显,它将被称为witin SUT。应该在测试的“断言”部分中使用shouldBeCalled(),以确认使用预期参数或在正确的时间调用了协作者。
最后的SUT和规范应该如下所示:
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的第二个“true”参数所规定的),因此,您希望使用后者调用$json_encode->getData(),因此:
$someFetcher->getData(array('id' => 1))->shouldBeCalled();https://stackoverflow.com/questions/25049275
复制相似问题