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

Symfony 5.4与PHPUnit 9.5测试时实体管理器不共享如何解决?

解决测试与应用代码使用不同EntityManager的问题

在Symfony 5.4 + PHPUnit 9.5的WebTestCase场景下,你遇到的问题根源是:测试类中通过static::getContainer()获取的EntityManager,和模拟HTTP请求时应用代码使用的EntityManager并非同一个实例(或存在缓存隔离),导致测试中创建的实体在请求上下文里无法被读取。

以下是两种可行的解决方法:

方法一:统一使用Client容器的EntityManager

直接从测试客户端的容器中获取EntityManager,确保测试操作和应用请求使用完全相同的实体管理器实例:

修改你的测试类代码:

<?php
use Doctrine\ORM\EntityManager;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class MyTest extends WebTestCase {
    protected EntityManager $entity_manager;

    protected function setUp(): void {
        // 先创建测试客户端
        static::$client = static::createClient();
        // 从客户端容器获取EntityManager
        $this->entity_manager = static::$client->getContainer()->get('doctrine')->getManager();
    }

    public function testShouldCreateAnEntityThatIsVisibleInTheAppCode() {
        $user = new User();
        $user->setFirstName('Joe');
        $user->setLastName('Bloggs');
        $user->setEmail('joe.bloggs@example.com');
        
        $this->entity_manager->persist($user);
        $this->entity_manager->flush();

        // 请求时无需指定完整域名,用相对路径即可
        $crawler = static::$client->request('GET', '/admin/show-users');
        $this->assertStringContainsString('joe.bloggs@example.com', $crawler->html());
    }
}

方法二:清除Client侧EntityManager的缓存

如果你需要保留测试容器的EntityManager,可在flush后清除客户端容器中EntityManager的一级缓存,强制它从数据库重新读取实体:

public function testShouldCreateAnEntityThatIsVisibleInTheAppCode() {
    $user = new User();
    $user->setFirstName('Joe');
    $user->setLastName('Bloggs');
    $user->setEmail('joe.bloggs@example.com');
    
    $this->entity_manager->persist($user);
    $this->entity_manager->flush();

    // 获取客户端的EntityManager并清除缓存
    $clientEntityManager = static::$client->getContainer()->get('doctrine')->getManager();
    $clientEntityManager->clear();

    $crawler = static::$client->request('GET', '/admin/show-users');
    $this->assertStringContainsString('joe.bloggs@example.com', $crawler->html());
}

额外注意事项

  • 测试中请求路径建议用相对路径(如/admin/show-users),而非完整域名,避免环境配置问题。
  • Symfony的WebTestCase默认会在每个测试结束后回滚事务,无需担心测试数据污染数据库。

内容的提问来源于stack exchange,提问作者CJ Dennis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 18:50:27