dmaicher/doctrine-test-bundle

Error bootstrap in PHPUnit Extension

Closed this issue ยท 2 comments

Hello,

First, let me thank you for this very handy bundle, that help me for many years now ๐Ÿš€

I'm used to bootstrap my databases using a PHPUnit extension for a while now (because it allows me to run few tests within the command line, and if the test to not requires a database, it is not bootstraped: a lot faster)

It was working like a charm, until I recently tried to update one of my projects to:

  • symfony/* >= 7.0
  • doctrine/orm >= 3.0
  • dama/doctrine-test-bundle >= 2.0

Now, when I run PHPUnit tests, I get the following error, while executing migrations

[Doctrine\DBAL\Exception\DatabaseRequired]                                                          
A database is required for the method: Doctrine\DBAL\Schema\AbstractSchemaManager::listTableNames.  

Tip

I was not sure it has anything to do with the project itself, so I created a reproducer project you can try on your own
https://github.com/yann-eugone/dama-doctrine-test-bundle-extension

Things I've tried so far:

  • if I move the extension code to tests/bootstrap.php: it works โœ”๏ธ
  • if I comment StaticDriver::setKeepStaticConnections(true); in DAMA\DoctrineTestBundle\PHPUnit\PHPUnitExtension::executeBeforeFirstTest: it works โœ”๏ธ

Yeah here the problem is that when your phpunit extension's DatabaseExtension::executeBeforeTest is called the bundle is already managing any database connection since StaticDriver::setKeepStaticConnections(true) was called in

public function executeBeforeFirstTest(): void
{
StaticDriver::setKeepStaticConnections(true);
}

This should fix it:

diff --git a/tests/Extension/DatabaseExtension.php b/tests/Extension/DatabaseExtension.php
index 23983c6..6a61f65 100644
--- a/tests/Extension/DatabaseExtension.php
+++ b/tests/Extension/DatabaseExtension.php
@@ -5,6 +5,7 @@ declare(strict_types=1);
 namespace App\Tests\Extension;
 
 use App\Kernel;
+use DAMA\DoctrineTestBundle\Doctrine\DBAL\StaticDriver;
 use PHPUnit\Framework\TestCase;
 use PHPUnit\Runner\BeforeTestHook;
 use Symfony\Bundle\FrameworkBundle\Console\Application;
@@ -26,33 +27,39 @@ final class DatabaseExtension implements BeforeTestHook
             return;
         }
 
-        $kernel = new Kernel($_ENV['APP_ENV'], (bool)$_ENV['APP_DEBUG']);
-        $kernel->boot();
-
-        $application = new Application($kernel);
-        $application->setAutoExit(false);
-
-        $output = new BufferedOutput();
-
-        foreach (
-            [
-                ['command' => 'doctrine:database:drop', '--if-exists' => true, '--force' => true],
-                ['command' => 'doctrine:database:create'],
-                ['command' => 'doctrine:migrations:migrate', '--no-all-or-nothing' => true],
-            ] as $input
-        ) {
-            $result = $application->run(
-                new ArrayInput(['--no-interaction' => true, '--verbose' => true, ...$input]),
-                $output,
-            );
-            if ($result !== Command::SUCCESS) {
-                throw new \RuntimeException($output->fetch());
+        StaticDriver::setKeepStaticConnections(false);
+
+        try {
+            $kernel = new Kernel($_ENV['APP_ENV'], (bool)$_ENV['APP_DEBUG']);
+            $kernel->boot();
+
+            $application = new Application($kernel);
+            $application->setAutoExit(false);
+
+            $output = new BufferedOutput();
+
+            foreach (
+                [
+                    ['command' => 'doctrine:database:drop', '--if-exists' => true, '--force' => true],
+                    ['command' => 'doctrine:database:create'],
+                    ['command' => 'doctrine:migrations:migrate', '--no-all-or-nothing' => true],
+                ] as $input
+            ) {
+                $result = $application->run(
+                    new ArrayInput(['--no-interaction' => true, '--verbose' => true, ...$input]),
+                    $output,
+                );
+                if ($result !== Command::SUCCESS) {
+                    throw new \RuntimeException($output->fetch());
+                }
             }
-        }
 
-        $kernel->shutdown();
+            $kernel->shutdown();
 
-        $this->initialized = true;
+            $this->initialized = true;
+        } finally {
+            StaticDriver::setKeepStaticConnections(true);
+        }
     }

And... It work like a charm again! Thank you very much for your help ๐Ÿ™