Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Testings Types from the Service Container doesn't find dependencies #36462

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
rgrassian opened this issue Apr 16, 2020 · 8 comments
Closed

Testings Types from the Service Container doesn't find dependencies #36462

rgrassian opened this issue Apr 16, 2020 · 8 comments

Comments

@rgrassian
Copy link

Symfony version(s) affected: 4.4.7

Description
In my case I can't test a type with a dependency, I get the following error :

ArgumentCountError: Too few arguments to function Symfony\Bridge\Doctrine\Form\Type\DoctrineType::__construct()

How to reproduce

class ContractCommercialGestureNewTypeTest extends TypeTestCase
{
    /**
     * @var CommercialGestureRepository|MockObject
     */
    protected $commercialGestureRepository;

    /**
     * @return void
     */
    protected function setUp(): void
    {
        $this->commercialGestureRepository = $this->createMock(CommercialGestureRepository::class);

        parent::setUp();
    }

    /**
     * @return void
     */
    public function testSubmitForm(): void
    {
        $contractCommercialGestureToCompare = new ContractCommercialGesture();
        $form = $this->factory->create(ContractCommercialGestureNewType::class, $contractCommercialGestureToCompare);
    }

    /**
     * @return array<FormExtensionInterface>
     */
    protected function getExtensions(): array
    {
        $type = new ContractCommercialGestureNewType($this->commercialGestureRepository);

        return [
            new PreloadedExtension([$type], []),
        ];
    }
}

Possible Solution

Additional context
The construct of my type :

    public function __construct(CommercialGestureRepository $commercialGestureRepository)
    {
        $this->commercialGestureRepository = $commercialGestureRepository;
    }

The link of the documentation :
https://symfony.com/doc/current/form/unit_testing.html#testings-types-from-the-service-container

@stof
Copy link
Member

stof commented Apr 16, 2020

Well, you will need to register the DoctrineExtension in your TypeTestCase if you rely on the Doctrine types in the form you test.
The TypeTestCase is not using the container (it does not even boot the kernel and does not even require having a kernel) to register form types.

@rgrassian
Copy link
Author

Thank you, how would you do this ? And should it be added to the documentation ?

@wouterj
Copy link
Member

wouterj commented Apr 16, 2020

See the next chapter in the docs you linked: https://symfony.com/doc/current/form/unit_testing.html#adding-custom-extensions

@VincentLanglet
Copy link
Contributor

See the next chapter in the docs you linked: https://symfony.com/doc/current/form/unit_testing.html#adding-custom-extensions

IMHO, this is not clear enough.

First, without documentation, I don't think everybody will know that the DoctrineOrmExtension is required for a form with a EntityType.

Then, the extension is not easy to use. You have to write

protected function getExtensions(): array
    {
        return [
            new DoctrineOrmExtension($registry),
        ];
    }

But you need a $registry !

If we go deep in some tests written by Symfony, we can find a way to get a $registry:

$entityManager = DoctrineTestHelper::createTestEntityManager();
$registry = $this->createMock(ManagerRegistry::class);

$registry->method('getManager')->willReturn($entityManager);
$registry->method('getManagerForClass')->willReturn($entityManager);

return $registry;

This can also be found in StackOverflow

But this only works with EntityRepository, not ServiceEntityRepository !
With a ServiceEntityRepository, you receive the following error message

TypeError: Argument 1 passed to FooRepository::__construct() must implement interface Doctrine\Persistence\ManagerRegistry, instance of Doctrine\ORM\EntityManager given

This error can be found on StackOverflow without any resolution.

Maybe I missed an easy solution but in my case, I only made it work with:

$factory = new TestRepositoryFactory();
$configuration->setRepositoryFactory($factory);
$entityManager = DoctrineTestHelper::createTestEntityManager($configuration);

$repository = $this->createMock(EntityRepository::class);
$repository->method('createQueryBuilder')->willReturn($this->createMock(QueryBuilder::class));
$factory->setRepository($entityManager, Foo::class, $repository);

Which is far from being easy.

@HeahDude
Copy link
Contributor

Hello @VincentLanglet, I agree we need a doc update, I have opened symfony/symfony-docs#13552.

The KernelTestCase (instead of the TypeTestCase) should be your way to go in this case, using the "real" form factory.

I think we should close here though as there is nothing we can do about it in core.

@VincentLanglet
Copy link
Contributor

The KernelTestCase (instead of the TypeTestCase) should be your way to go in this case, using the "real" form factory.

Indeed, the kernel would be useful.
But the TypeTestCase would still be necessary if I want to add form extensions and stuff, isn't it ?
Should the TypeTestCase extend the KernelTestCase then ?

@HeahDude
Copy link
Contributor

But the TypeTestCase would still be necessary if I want to add form extensions and stuff, isn't it ?
Should the TypeTestCase extend the KernelTestCase then ?

Both should not be related. The KernelTestCase is using the "real" container (based on test env config though) so you don't have to do anything more since the form factory will be loaded as a service and will register everything just like when your application is handling a request.

javiereguiluz added a commit to symfony/symfony-docs that referenced this issue May 18, 2020
This PR was squashed before being merged into the 3.4 branch.

Discussion
----------

[Form] Updated unit testing article

Ref symfony/symfony#36462.

Commits
-------

de0d1fb [Form] Updated unit testing article
@nicolas-grekas
Copy link
Member

Closing as that's related to the doc and this staled here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants