liip / LiipTestFixturesBundle

This bundles enables efficient loading of Doctrine fixtures in functional test-cases for Symfony applications
https://liip.ch
MIT License
168 stars 45 forks source link

Upgrade to 1.8/1.9.1 creates Kernel boot error #66

Closed floriansemm closed 3 years ago

floriansemm commented 4 years ago

I have updated fixtures-bundle from 1.7 to 1.8/1.9.1. After this update the following error is shown when I run controller-tests:

LogicException : Cannot access the container on a non-booted kernel. Did you forget to boot it?
vendor/symfony/framework-bundle/Test/TestContainer.php:144
vendor/symfony/framework-bundle/Test/TestContainer.php:152
vendor/symfony/framework-bundle/Test/TestContainer.php:106
vendor/liip/test-fixtures-bundle/src/Test/FixturesTrait.php:85
tests/App/Controller/AbstractFunctionalTestCase.php:70

Preconditions

  1. SF 4.4.8
  2. LiipTestFixturesBundle 1.8

Steps to reproduce

We have implemented a AbstractFunctionalTestCase class which implements the setUp() method to do all fixtures-load stuff for our controller-tests.

The method looks like this:

public function setUp()
{
     $this->client = $this->makeAuthenticatedClient();

     $fixtures = [
         // ...
     ];

     // ...

     $this->references = $this->loadFixtures($fixtures)->getReferenceRepository();

     // ...
}
alexislefebvre commented 4 years ago

Probably related to https://github.com/liip/LiipTestFixturesBundle/pull/62#issuecomment-622191412

alexislefebvre commented 4 years ago

You can try to use the new loginClient method added in the other bundle: https://github.com/liip/LiipFunctionalTestBundle/pull/567/files

alexislefebvre commented 4 years ago

I would like to remove getContainer() from this bundle and rely on pure Symfony code to fetch the container. And without any dependency like in #26

jandom commented 4 years ago

For anybody bumping into this, you can just over-write the trait method in your helper class/test class

use Doctrine\Common\DataFixtures\Executor\AbstractExecutor;

...

    /**
     * Override from FixturesTrait, fixtures trait doesn't support Symfony4 loading.
     */
    protected function loadFixtures(array $classNames = [], bool $append = false, ?string $omName = null, string $registryName = 'doctrine', ?int $purgeMode = null): ?AbstractExecutor
    {
        $dbToolCollection = static::$container->get('liip_test_fixtures.services.database_tool_collection');
        $dbTool = $dbToolCollection->get($omName, $registryName, $purgeMode, $this);
        $dbTool->setExcludedDoctrineTables($this->excludedDoctrineTables);

        return $dbTool->loadFixtures($classNames, $append);
    }
radoibogdan commented 3 years ago

Hello, I tried to override the loadFixtureFiles (i am using Alice with Liip) but now i have another error. Error: Call to a member function get() on null This is apparently from the [static::$container->get] line Any ideas would be appreciated. Thank you!

alexislefebvre commented 3 years ago

Try to boot the kernel before running the test, by adding this method in your class:

    public function setUp(): void
    {
        parent::setUp();

        self::bootKernel();
    }

Alternatively, you can stop using the Trait and use the bundle from the service, see this code (which is part of a PR but should work with the current version of this bundle).

radoibogdan commented 3 years ago

Hello Alexis et Merci beaucoup !

Your solution + the one from @jandom solves the issue.

Final code

use FixturesTrait;

public function setUp(): void
    {
        parent::setUp();

        self::bootKernel();
    }

public function loadFixtureFiles(array $paths = [], bool $append = false, ?string $omName = null, $registryName = 'doctrine', ?int $purgeMode = null): array
    {
        $dbToolCollection = self::$container->get('liip_test_fixtures.services.database_tool_collection');
        $dbTool = $dbToolCollection->get($omName, $registryName, $purgeMode, $this);
        $dbTool->setExcludedDoctrineTables($this->excludedDoctrineTables);

        return $dbTool->loadAliceFixture($paths, $append);
    }

public function assertHasErrors(InvitationCode $code, int $number = 0)
    {
        self::bootKernel();
        $errors = self::$container->get('validator')->validate($code);
        $messages = [];
        /** @var ConstraintViolation $error */
        foreach($errors as $error) {
            $messages[] = $error->getPropertyPath() . ' => ' . $error->getMessage();
        }
        $this->assertCount($number, $errors, implode(', ', $messages));
    }

public function testInvalidUsedCode(){
        $this->loadFixtureFiles([dirname(__DIR__) . '/fixtures/invitation_codes.yaml']);
        $this->assertHasErrors($this->getEntity()->setCode('54321'), 1); 
    }
alexislefebvre commented 3 years ago

Great! Do you still get an error if you remove that loadFixtureFiles function?

radoibogdan commented 3 years ago

Yes, I have this error :

LogicException: Cannot access the container on a non-booted kernel. Did you forg
et to boot it?
alexislefebvre commented 3 years ago

I think that issue is solved.