mercredi 22 juillet 2020

Testing a Symfony 3.4+ bundle with a database connection

I'm trying to determine the best way to configure a bundle for testing using Travis that makes a connection to a database. Normally when the bundle is used inside a project the DB connection is specified as part of the project configuration (config/packages/doctrine.yaml). However when using CI tests the bundle gets installed in the test project root and the dependencies in /vendor.

What I would like to do is configure a doctrine connection using a sqlite memory database, create the schema as part of the CI test and run my phpunit tests, all of which run fine if the bundle is installed in a normal Symfony project.

I'm getting totally frustrated trying to configure the database. I've been at this for a couple of days now trying to trace what is (not) going loading the configs.

I have a kernel which I load in my test class that extends KernelTestCase as follows:

class CommandSchedulerTest extends KernelTestCase
{
    /**
     * @var \Doctrine\ORM\EntityManagerInterface
     */
    private $entityManager;

    protected static function getKernelClass()
    {
        return TestKernel::class;
    }

    protected function setUp()
    {
        self::bootKernel();

        $this->entityManager = static::$kernel->getContainer()->get('doctrine')->getManager();
    }
...

And my kernel class:

<?php

namespace Xact\CommandScheduler\Tests;

use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\Routing\RouteCollectionBuilder;

class TestKernel extends Kernel
{
    use MicroKernelTrait;

    /**
     * @inheritDoc
     */
    public function registerBundles()
    {
        $bundles = [
            \Symfony\Bundle\FrameworkBundle\FrameworkBundle::class,
            \Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle::class,
            \Doctrine\Bundle\DoctrineCacheBundle\DoctrineCacheBundle::class,
            \Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class,
        ];

        foreach ($bundles as $class) {
            yield new $class();
        }
    }

    protected function configureRoutes(RouteCollectionBuilder $routes)
    {
        $confDir = $this->getProjectDir().'/Resources/config';
        $routes->import($confDir.'/routing.yaml');
    }

    protected function configureContainer(ContainerBuilder $c, LoaderInterface $loader)
    {
        $confDir = $this->getProjectDir().'/Resources/config';
        $loader->load($confDir . '/test/doctrine.yaml');
        $loader->load($confDir . '/test/framework.yaml');
    }
}

And for reference, my doctrine.yaml file:

doctrine:
    dbal:
        url: "sqlite:///:memory:"

I managed to hack the configuration loading process and I can see the contents of my framework.yaml file are being added to the parameters list. I also know the doctrine.yaml file is being parsed because if I add anything other than 'dbal' or 'orm' under the root I get an error. However I don't seem to get the connection in the list of parameters.

I'm getting errors like this:

1) Xact\CommandScheduler\Tests\CommandSchedulerTest::testSet
InvalidArgumentException: Doctrine ORM Manager named "" does not exist.

/var/projects/command-scheduler/vendor/doctrine/persistence/lib/Doctrine/Persistence/AbstractManagerRegistry.php:151
/var/projects/command-scheduler/Tests/CommandSchedulerTest.php:25

Which makes me think that my doctrine config is not being correctly loaded.

I have also tried adding the config via PrependExtensionInterface::prepend as I've read suggestions that loading db connections during the Kernel::configureContainer is too late. However this achieved nothing and presented other errors indicating that any config files loaded in the kernel are ignored.

I would deeply appreciate some help in determining if I am on the right track with this, am I trying to do something that can't be done? Have I missed something very basic in my setup? I don't know. What I do know is that I have lost a little more hair which is disturbing!

Many thanks in anticipation of help. Ian.

Aucun commentaire:

Enregistrer un commentaire