我仍然在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
.

意味着将使用与myClass的相同接口设置$ Condent的协作者对象。 当SUT中调用child-> getJsonquery()时,它将返回一个方法,而不是您希望它返回的字符串。

您想说的是,您的ArrayCollection将包含 not $ shink本身(这是一个协作者对象),但是协作者包裹的实体对象。你这样做:

$returnCollection = new ArrayCollection(array($child->getWrappedObject()));
.

另外,你不应该使用(即是多余的) 应该在同一个合作者,一个或那个中的()和willreturn() 其他是足够的。如果您指定了合作伙伴的意志 返回,很明显,它将被称为witin the sut。 应该在“断言”部分中使用()在测试中使用 为了确认合作员被预期调用 参数,或在合适的时间。

你的最终的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);
.

将在$查询中生成关联的阵列,即阵列('id'=> 1)(这是json_encode规定的第二个'true'参数的规定),因此您将期望$ somefetcher-> getdata()用后者调用,因此:

$someFetcher->getData(array('id' => 1))->shouldBeCalled();
.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top