You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Symfony 4测试时如何切换使用的数据库连接?

Switching Entity Manager to test_gui in Symfony Tests

Great question! Let's break down a few solid ways to make your userRegistrationDatabase function use the test_gui entity manager during tests, depending on how much you want to adjust your existing code.

Option 1: Environment Configuration Swap (Simplest Approach)

Symfony lets you override configuration per environment, so you can make the gui entity manager point to your test SQLite database when running tests. No changes to your business code needed!

  1. Create or update the test environment Doctrine config at config/packages/test/doctrine.yaml:
doctrine:
    dbal:
        connections:
            test_gui:
                url: '%env(resolve:DATABASE_TEST_GUI_URL)%'
                driver: pdo_sqlite
                # Add any other test-specific DB settings here
    orm:
        entity_managers:
            gui:  # Keep the original manager name, but map it to the test connection
                connection: test_gui
                mappings:
                    App:
                        is_bundle: false
                        dir: '%kernel.project_dir%/src/Entity'
                        prefix: 'App\Entity'
                        alias: App
  1. Update your .env.test file to define the test database URL:
DATABASE_TEST_GUI_URL="sqlite:///%kernel.project_dir%/var/data/test_gui.db"

Now when you run tests, $this->getDoctrine()->getManager("gui") will automatically use the test_gui connection—your business code stays exactly the same.

Option 2: Inject the Entity Manager (Cleanest, Most Maintainable)

Instead of hardcoding getManager("gui") in your service, inject the entity manager directly. This makes swapping it for tests trivial and aligns with Symfony's best practices.

Step 1: Refactor your service to use dependency injection

use Doctrine\ORM\EntityManagerInterface;

class UserManagement
{
    private EntityManagerInterface $guiEntityManager;

    // Inject the gui entity manager via constructor
    public function __construct(EntityManagerInterface $guiEntityManager)
    {
        $this->guiEntityManager = $guiEntityManager;
    }

    public function userRegistrationDatabase(String $email, String $keyRockId): object { 
        $user = new User(); 
        $user->setUserName($email); 
        $user->setEmail($email); 
        $user->setEnabled(true); 
        $userRole = ['ROLE_USER','ROLE_ADMIN']; 
        $user->addRole(implode(",",$userRole)); 
        $user->setKeyrockId($keyRockId); 

        // Use the injected manager instead of fetching it
        $this->guiEntityManager->persist($user); 
        $this->guiEntityManager->flush(); 
        return $user; 
    }
}

Step 2: Configure the service in config/services.yaml

Bind the gui entity manager to your service:

services:
    App\Service\UserManagement:
        arguments:
            $guiEntityManager: '@doctrine.orm.gui_entity_manager'

Step 3: Override for tests in config/packages/test/services.yaml

Swap the injected manager for test_gui:

services:
    App\Service\UserManagement:
        arguments:
            $guiEntityManager: '@doctrine.orm.test_gui_entity_manager'

Now your test will automatically use the test_gui manager without any extra code in the test function.

Option 3: Manual Swap with Reflection (Quick Fix, Not Ideal)

If you can't modify the service or config right now, you can use reflection to force the service to use the test manager. This is a temporary workaround—prefer the other options long-term.

public function testUserRegistrationDatabase() { 
    $userManager = self::$kernel->getContainer()->get('test.'. UserManagement::class); 
    $testEntityManager = self::$kernel->getContainer()->get('doctrine')->getManager('test_gui');
    
    // Use reflection to access the private $entityManager property in UserManagement
    $reflection = new \ReflectionClass($userManager);
    $entityManagerProp = $reflection->getProperty('entityManager');
    $entityManagerProp->setAccessible(true);
    $entityManagerProp->setValue($userManager, $testEntityManager);
    
    $mail = 'notexistinguser@mail.com'; 
    $keyRockId = '45091fd63a1'; 
    $user = $userManager->userRegistrationDatabase($mail,$keyRockId); 
}

Just note: This relies on the internal property name ($entityManager) staying the same, so it's fragile if you refactor later.


内容的提问来源于stack exchange,提问作者Stefano Maglione

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:38:47