Symfony & Doctrine问题:PHPUnit测试中实体更新后搜索无变化
这种情况我在Symfony+PHPUnit的项目里踩过好几次坑,大概率是实体管理器(EntityManager)的状态同步或者事务处理环节出了问题,给你几个具体的排查方向:
检查服务中是否执行了
flush()
最常见的问题就是只修改了实体的字段值,但没有调用EntityManager的flush()方法将变更同步到数据库。你的GestionnaireFinalisation服务里的代码应该类似这样:public function finaliserParAuteur(Finalisation $finalisation): void { $finalisation->setFinaliseParAuteur(true); $this->entityManager->flush(); // 这行绝对不能少! }如果漏掉
flush(),实体的变更只会停留在内存中,数据库里的数据不会更新,重新查询自然看不到变化。确认测试与服务使用的是同一个EntityManager实例
测试里从容器获取的EntityManager,和服务依赖注入的必须是同一个实例。如果服务里手动创建了新的EntityManager(比如new EntityManager(...)),那两个实例的状态是完全隔离的,服务里的变更不会同步到测试用的EM中。
确保服务是通过构造函数注入EntityManager:class GestionnaireFinalisation { public function __construct(private EntityManagerInterface $entityManager) {} }测试里则通过容器获取:
$em = self::$container->get(EntityManagerInterface::class);测试中重新从数据库查询实体,不要直接用原引用
如果你在测试里直接用最初创建的$finalisation对象断言字段值,可能会因为内存引用的原因看到“已更新”的假象,但实际上数据库并没有同步。正确的做法是通过ID重新查询实体:// 执行服务操作 $gestionnaire->finaliserParAuteur($finalisation); // 重新从EntityManager获取实体 $updatedFinalisation = $em->find(Finalisation::class, $finalisation->getId()); // 断言字段值 $this->assertTrue($updatedFinalisation->isFinaliseParAuteur());检查事务与测试的隔离设置
PHPUnit默认会给每个测试方法开启事务,测试结束后自动回滚。但如果你的服务里手动开启了独立事务,或者测试中手动控制了事务提交,可能会导致变更没有生效。确保所有操作都在同一个事务上下文内执行。验证实体字段的ORM映射正确性
最后可以检查一下Finalisation实体中finaliseParAuteur字段的映射是否正确,比如:#[ORM\Column(name: 'finalise_par_auteur', type: 'boolean', nullable: false, options: ['default' => false])] private bool $finaliseParAuteur = false;确认字段名、类型和默认值都和数据库列匹配,避免因映射错误导致变更无法持久化。
先从“忘记调用flush()”这个最常见的问题开始排查,一般都能解决。
内容的提问来源于stack exchange,提问作者zskiredj

