Symfony:如何测试将FormType与构造函数一起使用的CollectionType

时间:2017-06-13 17:01:17

标签: php forms symfony unit-testing

我有一个表单类型StoreProfileType,它使用SocialProfileType创建CollectionType来添加用户喜欢的社交个人资料。

两种表单类型SocialProfileTypeStoreProfileType都有一个需要EntityManager的构造函数。

在测试期间,我可以将EntityManager传递给StoreProfileType,但我不知道如何将其传递给嵌入的表单类型SocialProfileType

这是StoreProfileType

class StoreProfileType extends AbstractType
{
    /** @var ObjectManager */
    private $manager;

    /**
     * @param EntityManagerInterface $manager
     */
    public function __construct(EntityManagerInterface $manager)
    {
        $this->manager = $manager;
    }

    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('name', TextType::class)
            ->add('primaryEmail', EmailType::class)
            ->add('logoUploadingFile', FileType::class, ['required' => false])
            ->add('description', TextareaType::class, ['required' => false])
            ->add('address', AddressType::class, ['data_class' => AddressEmbeddable::class, 'empty_data' => new AddressEmbeddable([])])
            ->add('socialProfiles', CollectionType::class, [
                'entry_type' => SocialProfileType::class,
                'entry_options' => ['store' => $builder->getData()],
                'allow_add'  => true,
                'allow_delete' => true,
                'by_reference' => false,
                'label' => false
            ]);

        // Transform the email string into a value object
        $builder->get('primaryEmail')->addModelTransformer(new EmailTransformer($this->manager));
    }
}

FormType SocialProfileType就是:

class SocialProfileType extends AbstractType
{
    /** @var EntityManagerInterface */
    private $entityManager;

    /**
     * @param EntityManagerInterface $manager
     */
    public function __construct(EntityManagerInterface $manager)
    {
        $this->entityManager = $manager;
    }

    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('profileUrl', UrlType::class);
        $builder->get('profileUrl')->addModelTransformer(new DomainEmbeddableTransformer($this->entityManager));
        $builder->addModelTransformer(new SocialProfileTransformer($this->entityManager, $options));
    }

    /**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => SocialProfile::class,
            'store' => Store::class,
            'company' => Company::class
        ]);
    }
}

我在services.yml中设置了两个表单,以便在构造函数中注入EntityManager

form.type.store:
    class: AppBundle\Form\Type\StoreProfileType
    arguments: ["@doctrine.orm.entity_manager"]
    tags:
        - { name: form.type}

form.type.social_profile:
        class: AppBundle\Form\Type\SocialProfileType
        arguments: ["@doctrine.orm.entity_manager"]
        tags:
            - { name: form.type}

在渲染表单时一切正常,但我不知道如何测试表单。

这是我使用的单位测试方法:

public function testSubmitValidData()
{
    $formData = [
        'name'              => '',
        'primaryEmail'      => 'test@example.com',
        'logoUploadingFile' => '',
        'description'       => '',
    ];

    $mockStoreRepository = $this->getMockBuilder(EntityRepository::class)
        ->disableOriginalConstructor()
        ->getMock();
    $mockStoreRepository->method('findOneBy')->willReturn($mockStoreRepository);

    // Mock the FormType: entity
    $mockEntityManager = $this->getMockBuilder(EntityManagerInterface::class)
        ->disableOriginalConstructor()
        ->getMock();
    $mockEntityManager->method('getRepository')->willReturn($mockStoreRepository);

    /** @var EntityManagerInterface $mockEntityManager */
    $type = new StoreProfileType($mockEntityManager);
    $form = $this->factory->create($type);

    $form->submit($formData);

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

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

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

正如您所看到的,我可以在EntityManager中注入StoreFormType但我无法将其注入SocialProfileType,因为这是Symfony在呈现表单时直接完成的工作。

在测试EntityManager时如何将SocialProfileType传递给StoreProfileType

我收到的错误(显然)是这样的:

  

1)AppBundle \ Tests \ Unit \ Form \ Type \ StoreTypeTest :: testSubmitValidData   TypeError:传递给的参数1   AppBundle \ Form \ Type \ SocialProfileType :: __ construct()必须实现   接口Doctrine \ ORM \ EntityManagerInterface,没有给出,调用   /Users/Aerendir/Documents/JooServer/_Projects/Coommercio/Apps/app-trust-back-me-www/vendor/symfony/symfony/src/Symfony/Component/Form/FormRegistry.php   在第90行

" ...没有给出......" ,这是正确的,因为我真的没有'传递它......但是......我怎么能在它嵌入时传递它?

0 个答案:

没有答案