Symfony Unit Test Form with Collections

I am trying to execute my first unit tests and functional tests with Symfony3 / PHPunit and I am not finding a solution to my problem.

To keep it simple, I am trying to create a Unit Test form created to manage Users

and Groups

(provided by FOSUserBundle)

I followed the steps of the Symfony documentation to validate my form and I have already solved some problems regarding getExtensions()

etc. to be able to run my test without errors

Here is mine UserType.php

:

<?php

...

class UserType extends BaseCrudForm
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        parent::buildForm($builder, $options);

        $builder
            ->add('username', null, array('label' => 'label.username'))
            ->add('email', EmailType::class, array(
                'label' => 'label.email',
                'constraints' => array(
                    new Email()
                )
            ))
            ->add('enabled', CheckboxType::class, array('label' => 'label.enabled', 'required' => false))
            ->add('groups', EntityType::class, array(
                'class' => 'Acme\AdminBundle\Entity\Group',
                'multiple' => true,
                'required' => false,
            ))
            ->add('avatarImageFile', FileType::class, array('label' => 'label.avatar', 'required' => false))
        ;
    }

    ...

}

      

and mine UserTypeTest.php

(I left my tests in it):

<?php

...

class UserTypeTest extends BaseTypeTestCase
{
    public function testSubmitValidData()
    {
        $formData = array(
            'username' => 'nathalie_' . time(),
            'email' => 'nathalie_' . time() . '@portman.fr',
            'enabled' => true,
            'plainPassword' => 'pa$$word',

            ///// SOLUTION 1
            'groups' => array(
                $this->em->getRepository('AcmeAdminBundle:Group')->find(1)
            ),
            ///// SOLUTION 2
            'groups' => array(1),
        );

        $form = $this->factory->create(UserType::class);

        $user = User::fromArray($formData);

        $form->submit($formData);

        $this->assertTrue($form->isSynchronized());

        // dump($user, $form->getData());

        $this->assertEquals($user, $form->getData()); //Fails

        $view = $form->createView();
        $children = $view->children;

        foreach(array_keys($formData) as $key) {
            $this->assertArrayHasKey($key, $children);
        }
    }
}

      

Problem:

The assertion $this->assertEquals($user, $form->getData());

fails because the collection is User::groups

not equal

Solution 1 doesn't work (see code above)

The collection $user

is ok but the form data is empty

Solution 2 doesn't work either (see code above)

The form data is ok, but the collection $user

is created with a simple one array(1)

(see logic)

Question

How could I properly set up my User object and my form at the same time with the same information (as described in the Symfony documentation linked at the top of this topic)?

Note: as I said, I'm new with Unit Tests, so feel free to tell me if I miss the point

Edit

Here is the function fromArray

implemented as Trait

in the user entity:

<?php

namespace Acme\AdminBundle\Traits;    

use Doctrine\Common\Util\Inflector;

trait FromArrayTrait
{
    /**
     * @param array $data
     * @return self
     */
    public static function fromArray(array $data)
    {
        $object = new self;

        foreach ($data as $key => $value) {
            $method = 'set' . Inflector::classify($key);

            if (method_exists($object, $method)) {
                call_user_func(array($object, $method), $value);
            }
        }

        return $object;
    }
}

      

+3


source to share





All Articles