Pregunta

Todavía estoy fresco en PHPSPEC, pero por lo general estoy encontrando una solución cuando lucho con algo, pero este es difícil.

He intentado muchos enfoques diferentes y no he encontrado una solución.Estoy usando Symfony2.

Tengo una clase que quiero probar:

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;
    }

}

Y aquí es lo que parece mi clase de especificaciones:

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);
    }

}

y después de ejecutar phpspec Estoy recibiendo este error:

warning: json_decode() expects parameter 1 to be string, object given in

No tengo idea de cómo resolver este problema.Si alguien tiene una pista, por favor ayuda.

¿Fue útil?

Solución

Este es un bloqueo común con PHPSPEC, la Declaración:

   MyClass $child

significa que se establecerá un objeto colaborador de $ hijo con la misma interfaz de MyClass. Cuando el niño-> getJsonquery () se llama en el SUT (clase que está probando), devolverá una METEDHPROPHECY no la cadena que espera que regrese.

Lo que quiere decir es que su ArrayCollection contendrá no $ hijo en sí (que es un objeto colaborador), pero el objeto real que el colaborador está envuelto. Lo haces así:

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

Además, no debe estar usando (es decir, es superfluo) ambos en caso de recordar () y WillReturn () en el mismo colaborador, uno o el otro es suficiente. Si ha especificado lo que el colaborador será Devolución, está claro que va a llamarse con el SUT. Debería ser usado () se debe utilizar en la parte "Asfirmación" de la prueba en Para confirmar que el colaborador fue llamado con el esperado. argumentos, o en el momento adecuado.

Su último SUT y la especificación deben verse algo así:

   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);
    }

}

también, la línea

$query = \json_decode($child->getJsonQuery(), true);

producirá una matriz asociada en $ consulta, es decir, matriz ('ID'=> 1) (esto es lo que el segundo 'argumento' verdadero 'a JSON_ENCODE ESTIPULA), por lo tanto, esperaría $ PAYFINCHER-> GetData () a ser llamado con este último, por lo tanto:

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top