如何使用Zenstruck Foundry测试Symfony API并自动清理测试对象?
问题:Zenstruck Foundry测试Symfony API时的对象持久化与自动清理需求
我在使用Zenstruck Foundry测试Symfony API时,希望创建对象供API校验使用,同时测试结束后自动销毁对象,避免污染后续测试。
测试代码如下:
public function listEventType(): void { // Init kernel browser $this->init(); // create object $factory = EventTypeFactory::new(); $eventType = $factory ->create(['name' => 'EventType 1']); // ask api to send me back a list of eventType $arrayResponse = $this->getJsonResponse('GET', 'api/eventType'); // Assert success and that there is only one self::assertResponseIsSuccessful(); self::assertEquals(1, $arrayResponse['totalItems']); self::assertCount(1, $arrayResponse['items']); }
我尝试在工厂初始化时使用withoutPersisting()方法,但此时API调用返回结果数量为0:
protected function initialize(): self { return $this ->withoutPersisting() ; }
目前我采用「工厂不持久化+测试后手动清理」的临时方案,请问有没有更优的解决办法?
解决方案
方法1:利用Symfony测试的自动事务回滚机制
Symfony的WebTestCase/KernelTestCase默认会为每个测试方法启动数据库事务,测试结束后自动回滚所有操作。这是最简洁的方案:
- 直接使用Foundry的
create()方法持久化对象(默认行为),API可正常查询到数据; - 测试执行完毕后,Symfony自动回滚事务,数据库不会留下测试数据,完全不会污染后续测试。
你的测试代码无需额外修改,保持原样即可。
方法2:手动控制持久化(特殊场景适用)
如果需要先创建未持久化对象,后续再手动持久化供API查询,可使用如下方式:
public function listEventType(): void { $this->init(); // 创建未持久化的对象实例 $eventType = EventTypeFactory::new()->withoutPersisting()->create(['name' => 'EventType 1']); // 手动持久化到数据库 $this->manager()->persist($eventType); $this->manager()->flush(); // 执行API请求并断言 $arrayResponse = $this->getJsonResponse('GET', 'api/eventType'); self::assertResponseIsSuccessful(); self::assertEquals(1, $arrayResponse['totalItems']); self::assertCount(1, $arrayResponse['items']); }
测试结束后,Symfony的自动事务回滚仍会清理数据,无需手动删除。
关于withoutPersisting()导致API返回0的原因
调用withoutPersisting()时,Foundry仅创建内存中的对象实例,不会将其保存到数据库。而API接口查询的是数据库数据,因此无法获取到未持久化的对象,导致返回数量为0。
内容的提问来源于stack exchange,提问作者LinChan
相关产品推荐
相关产品推荐

