Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Doctrine Test Bundle Laravel Package

dama/doctrine-test-bundle

Symfony test bundle that speeds up Doctrine tests by reusing static DBAL connections and wrapping each test in a transaction that’s rolled back for isolation. Also provides a PSR-6 static array cache for Doctrine metadata/query caching to reduce boot time and memory.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require --dev dama/doctrine-test-bundle
    
  2. Enable the Bundle (in config/bundles.php):

    DAMA\DoctrineTestBundle\DAMADoctrineTestBundle::class => ['test' => true],
    
  3. Configure PHPUnit (phpunit.xml):

    <extensions>
        <bootstrap class="DAMA\DoctrineTestBundle\PHPUnit\PHPUnitExtension" />
    </extensions>
    
  4. Verify DBAL Configuration (if using DBAL < 4):

    # config/packages/doctrine.yaml
    doctrine:
        dbal:
            connections:
                default:
                    use_savepoints: true
    

First Use Case

Run a test that interacts with Doctrine (e.g., WebTestCase or KernelTestCase). The bundle will:

  • Auto-start a transaction before each test.
  • Roll back changes after each test (unless skipped).
  • Cache metadata and queries in-memory for speed.

Example:

// src/Tests/Entity/UserTest.php
public function testUserCreation(): void
{
    $user = new User();
    $user->setName('Test User');

    $entityManager = self::getContainer()->get('doctrine')->getManager();
    $entityManager->persist($user);
    $entityManager->flush();

    $this->assertEquals(1, $entityManager->getRepository(User::class)->count([]));
    // Changes rolled back automatically after test
}

Implementation Patterns

Workflows

  1. Transactional Tests:

    • Use #[SkipDatabaseRollback] to exclude specific tests/classes from rollback:
      #[SkipDatabaseRollback]
      public function testDebugState(): void
      {
          // Changes persist after test
      }
      
  2. Debugging Failed Tests:

    • Temporarily commit changes to inspect state:
      public function testDebugState(): void
      {
          // ... test logic
          \DAMA\DoctrineTestBundle\Doctrine\DBAL\StaticDriver::commit();
          die; // Inspect DB state
      }
      
  3. Custom Connection Keys (for read/write replicas):

    dama_doctrine_test:
        connection_keys:
            default:
                primary: primary_key
                replicas:
                    replica_one: replica_key
    
  4. Disabling Features:

    dama_doctrine_test:
        enable_static_connection: false
        enable_static_query_cache: false
    

Integration Tips

  • Fixtures: Use doctrine/doctrine-fixtures-bundle with load() in setUp() (changes rolled back automatically).
  • Behat: Enable the extension in behat.yml:
    extensions:
        DAMA\DoctrineTestBundle\Behat\ServiceContainer\DoctrineExtension: ~
    
  • Performance: Disable caching for slow tests:
    dama_doctrine_test:
        enable_static_meta_data_cache: false
    

Gotchas and Tips

Pitfalls

  1. Implicit Transactions:

    • Queries like ALTER TABLE, DROP TABLE, or CREATE INDEX may commit transactions implicitly. Error:
      PDOException: SAVEPOINT DOCTRINE2_SAVEPOINT_X does not exist
      
    • Fix: Avoid DDL in tests or use #[SkipDatabaseRollback].
  2. Replica Inconsistencies:

    • By default, primary/replica connections share the same driver. Override with connection_keys if needed:
      dama_doctrine_test:
          connection_keys:
              default:
                  primary: primary_key
                  replicas:
                      replica_one: replica_key
      
  3. PHPUnit Version:

    • Requires PHPUnit 11/12/13. Use SYMFONY_PHPUNIT_VERSION to enforce version:
      SYMFONY_PHPUNIT_VERSION=12 php bin/phpunit
      

Debugging

  • Transaction State: Check active savepoints with:

    $connection = $entityManager->getConnection();
    $connection->getWrappedConnection()->getTransactionNestingLevel();
    
  • Cache Issues: Clear static caches manually if tests behave unexpectedly:

    \DAMA\DoctrineTestBundle\Doctrine\DBAL\StaticDriver::clearStaticConnections();
    

Extension Points

  1. Custom Middleware: Register middleware with higher priority:

    # config/services.yaml
    services:
        App\Doctrine\TestMiddleware:
            tags: [doctrine.middleware]
    
  2. Override StaticDriver: Extend StaticDriver to customize behavior (e.g., logging):

    class CustomStaticDriver extends \DAMA\DoctrineTestBundle\Doctrine\DBAL\StaticDriver
    {
        public function beginTransaction(): void
        {
            \Log::info('Transaction started');
            parent::beginTransaction();
        }
    }
    

    Register it in config/packages/doctrine_test.yaml:

    dama_doctrine_test:
        static_driver_class: App\Doctrine\CustomStaticDriver
    

Tips

  • Test Speed: Enable all static features for maximum performance:
    dama_doctrine_test:
        enable_static_connection: true
        enable_static_meta_data_cache: true
        enable_static_query_cache: true
    
  • Large Datasets: Disable caching if memory usage is high:
    dama_doctrine_test:
        enable_static_query_cache: false
    
  • CI/CD: Use #[SkipDatabaseRollback] for integration tests that require persisted state.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport