How to load form types in tests

前端 未结 3 1272
长发绾君心
长发绾君心 2020-12-19 09:14


        
相关标签:
3条回答
  • 2020-12-19 09:52

    You must implements the getExtensions methods that build the two mocked form types used in the form: PlacesAutocompleteType and EntityType

    This solutions work for me:

    <?php
    
    
    namespace Acme\DemoBundle\Tests\Form;
    
    
    use Doctrine\Common\Collections\ArrayCollection;
    use Doctrine\ORM\Mapping\ClassMetadata;
    use Ivory\GoogleMapBundle\Form\Type\PlacesAutocompleteType;
    use Symfony\Bridge\Doctrine\Form\Type\EntityType;
    use Symfony\Component\Form\PreloadedExtension;
    use Symfony\Component\Form\Test\TypeTestCase;
    use Acme\DemoBundle\Entity\Venue;
    use Acme\DemoBundle\Form\VenueType;
    
    class VenueTypeTest extends TypeTestCase
    {
    
    public function testSubmitValidData() {
        $formData = array(
            'title' => 'Hello World',
        );
    
        $type = new VenueType();
        $form = $this->factory->create($type);
    
        $object = new Venue();
        $object->setTitle('Hello World');
    
        // submit the data to the form directly
        $form->submit($formData);
    
        $this->assertTrue($form->isSynchronized());
        $this->assertEquals($object, $form->getData());
    
        $view = $form->createView();
        $children = $view->children;
    
        foreach (array_keys($formData) as $key) {
            $this->assertArrayHasKey($key, $children);
        }
    }
    
    
    protected function getExtensions()
    {
    
        // Mock the FormType: places_autocomplete
    
        // See Ivory\GoogleMapBundle\Tests\Form\Type\PlacesAutocompleteTypeTest
        $placesAutocompleteHelperMock = $this->getMockBuilder('Ivory\GoogleMap\Helper\Places\AutocompleteHelper')
            ->disableOriginalConstructor()
            ->getMock();
    
        $requestMock = $this->getMock('Symfony\Component\HttpFoundation\Request');
        $requestMock
            ->expects($this->any())
            ->method('getLocale')
            ->will($this->returnValue('en'));
    
        $placesAutocompleteType = new PlacesAutocompleteType(
            $placesAutocompleteHelperMock,
            $requestMock
        );
    
        // Mock the FormType: entity
        $mockEntityManager = $this->getMockBuilder('\Doctrine\ORM\EntityManager')
            ->disableOriginalConstructor()
            ->getMock();
    
        $mockRegistry = $this->getMockBuilder('Doctrine\Bundle\DoctrineBundle\Registry')
            ->disableOriginalConstructor()
            ->getMock();
    
        $mockRegistry->expects($this->any())->method('getManagerForClass')
            ->will($this->returnValue($mockEntityManager));
    
        $mockEntityManager ->expects($this->any())->method('getClassMetadata')
            ->withAnyParameters()
            ->will($this->returnValue(new ClassMetadata('entity')));
    
        $repo = $this->getMockBuilder('Doctrine\ORM\EntityRepository')
            ->disableOriginalConstructor()
            ->getMock();
    
        $mockEntityManager ->expects($this->any())->method('getRepository')
            ->withAnyParameters()
            ->will($this->returnValue($repo));
    
        $repo->expects($this->any())->method('findAll')
            ->withAnyParameters()
            ->will($this->returnValue(new ArrayCollection()));
    
    
        $entityType = new EntityType($mockRegistry);
    
    
    
        return array(new PreloadedExtension(array(
            'places_autocomplete' => $placesAutocompleteType,
            'entity' => $entityType,
        ), array()));
    }
    }
    

    Hope this help. Let me know.

    0 讨论(0)
  • 2020-12-19 09:52

    This is in addition to @Matteo's solution, in case anyone else runs into the same complications mocking the EntityType dependencies. This gets the QueryBuilder to have the select() and from() methods called by default, which mirrors what happens on a functional kernel load and was missing on the test runs (parser was returning "SELECT WHERE ..."). Note that the class value in the entity field configuration array must be written out longhand, e.g. 'class' => 'AcmeBundle\Entity\MyClass', rather than the shorthand 'class' => 'AcmeBundle:MyClass' just for the sake of the mock repository.

    ...
    
    use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
    use Doctrine\ORM\Configuration;
    use Doctrine\ORM\Mapping\ClassMetadata;
    use Doctrine\ORM\QueryBuilder;
    use Symfony\Bridge\Doctrine\Form\Type\EntityType;
    use Symfony\Component\Form\Extension\Core\CoreExtension;
    use Symfony\Component\Form\Extension\Validator\Type\FormTypeValidatorExtension;
    use Symfony\Component\Form\Forms;
    use Symfony\Component\Form\PreloadedExtension;
    use Symfony\Component\Form\Test\TypeTestCase;
    use Symfony\Component\Validator\ConstraintViolationList;
    
    class MyTypeCase extends TypeTestCase
    {
    
        ...
    
        protected function getExtensions()
        {
            // mock entity manager
            $entityManager = $this->getMockBuilder('\Doctrine\ORM\EntityManager')
                ->disableOriginalConstructor()
                ->setMethods(array('getClassMetadata', 'getRepository'))
                ->getMock()
            ;
    
            // this method will be mocked specific to the class name when provided
            // by the mocked repository below - this can be generic here
            $entityManager->expects($this->any())
                ->method('getClassMetadata')
                ->will($this->returnValue(new ClassMetadata('entity')))
            ;
    
            $parent = $this;
    
            $entityManager->expects($this->any())
                ->method('getRepository')
                ->will($this->returnCallback(function($entityName) use ($parent) {
    
                    // if ever the Doctrine\ORM\Query\Parser is engaged, it will check for
                    // the existence of the fields used in the DQL using the class metadata
                    $classMetadata = new ClassMetadata($entityName);
    
                    if (preg_match('/[^a-z]MyClass$/i', $entityName)) {
                        $classMetadata->addInheritedFieldMapping(array('fieldName' => 'someField', 'columnName' => 'some_field'));
                        $classMetadata->addInheritedFieldMapping(array('fieldName' => 'anotherField', 'columnName' => 'another_field'));
                    }
    
                    // mock statement
                    $statement = $parent->getMockBuilder('\Doctrine\DBAL\Statement')
                        ->disableOriginalConstructor()
                        ->getMock()
                    ;
    
                    // mock connection
                    $connection = $parent->getMockBuilder('\Doctrine\DBAL\Connection')
                        ->disableOriginalConstructor()
                        ->setMethods(array('connect', 'executeQuery', 'getDatabasePlatform', 'getSQLLogger', 'quote'))
                        ->getMock()
                    ;
    
                    $connection->expects($parent->any())
                        ->method('connect')
                        ->will($parent->returnValue(true))
                    ;
    
                    $connection->expects($parent->any())
                        ->method('executeQuery')
                        ->will($parent->returnValue($statement))
                    ;
    
                    $connection->expects($parent->any())
                        ->method('getDatabasePlatform')
                        ->will($parent->returnValue(new PostgreSqlPlatform()))
                    ;
    
                    $connection->expects($parent->any())
                        ->method('quote')
                        ->will($parent->returnValue(''))
                    ;
    
                    // mock unit of work
                    $unitOfWork = $parent->getMockBuilder('\Doctrine\ORM\UnitOfWork')
                        ->disableOriginalConstructor()
                        ->getMock()
                    ;
    
                    // mock entity manager
                    $entityManager = $parent->getMockBuilder('\Doctrine\ORM\EntityManager')
                        ->disableOriginalConstructor()
                        ->setMethods(array('getClassMetadata', 'getConfiguration', 'getConnection', 'getUnitOfWork'))
                        ->getMock()
                    ;
    
                    $entityManager->expects($parent->any())
                        ->method('getClassMetadata')
                        ->will($parent->returnValue($classMetadata))
                    ;
    
                    $entityManager->expects($parent->any())
                        ->method('getConfiguration')
                        ->will($parent->returnValue(new Configuration()))
                    ;
    
                    $entityManager->expects($parent->any())
                        ->method('getConnection')
                        ->will($parent->returnValue($connection))
                    ;
    
                    $entityManager->expects($parent->any())
                        ->method('getUnitOfWork')
                        ->will($parent->returnValue($unitOfWork))
                    ;
    
                    // mock repository
                    $repo = $parent->getMockBuilder('\Doctrine\ORM\EntityRepository')
                        ->setConstructorArgs(array($entityManager, $classMetadata))
                        ->setMethods(array('createQueryBuilder'))
                        ->getMock()
                    ;
    
                    $repo->expects($parent->any())
                        ->method('createQueryBuilder')
                        ->will($parent->returnCallback(function($alias) use ($entityManager, $entityName) {
                            $queryBuilder = new QueryBuilder($entityManager);
                            $queryBuilder->select($alias)
                                ->from($entityName, $alias)
                            ;
                            return $queryBuilder;
                        }))
                    ;
    
                    return $repo;
                }))
            ;
    
            // mock registry
            $registry = $this->getMockBuilder('\Doctrine\Bundle\DoctrineBundle\Registry')
                ->disableOriginalConstructor()
                ->setMethods(array('getManagerForClass'))
                ->getMock()
            ;
    
            $registry->expects($this->any())
                ->method('getManagerForClass')
                ->will($this->returnValue($entityManager))
            ;
    
            // build the extensions
            $extensions = new PreloadedExtension(
                array(
                    'entity' => new EntityType($registry),
                ),
                array()
            );
    
            return array($extensions);
        }
    }
    
    0 讨论(0)
  • 2020-12-19 09:57

    This is in addition to @Matteo's solution - when You use Mockery, You can get EntityType this:

    $mockEntityManager = \Mockery::mock('\Doctrine\ORM\EntityManager');
    $mockRegistry = \Mockery::mock('Doctrine\Bundle\DoctrineBundle\Registry');
    $mockRegistry->shouldReceive('getManagerForClass')->andReturn($mockEntityManager);
    $mockEntityManager->shouldReceive('getClassMetadata')->andReturn(new ClassMetadata('entity'));
    $repo = \Mockery::mock('Doctrine\ORM\EntityRepository');
    $mockEntityManager->shouldReceive('getRepository')->andReturn($repo);
    $repo->shouldReceive('findAll')->andReturn(new ArrayCollection());
    $entityType = new EntityType($mockRegistry);
    
    0 讨论(0)
提交回复
热议问题