Symfony 6.3控制器集成测试:Mock FooRepository未触发调用问题
解决Symfony 6.3集成测试中Mock仓库未被调用的问题
你遇到的问题核心是:创建的Mock仓库实例没有替换Symfony容器中的真实仓库,导致控制器在处理请求时依然使用真实仓库访问数据库,Mock的调用验证自然失败。
修复步骤及代码示例
修改测试代码,将Mock实例注入到Symfony服务容器中,替换掉原有的真实仓库:
public function testFoo() { // 初始化测试用的实体对象 $foo = new Foo(); $foo->setName('test-foo'); // 创建FooRepository的Mock并设置调用预期 $fooRepository = $this->createMock(FooRepository::class); $fooRepository->expects(self::once()) ->method('findOneBy') ->with(['name' => 'test-foo']) // 可选:验证调用时的参数是否符合预期 ->willReturn($foo); // 将Mock替换到Symfony容器中,覆盖真实的仓库服务 $this->getContainer()->set(FooRepository::class, $fooRepository); // 发起请求 $this->client->jsonRequest('GET', '/foo/'.$foo->getName()); // 可选:验证响应结果 $this->assertResponseIsSuccessful(); $responseData = json_decode($this->client->getResponse()->getContent(), true); $this->assertEquals('test-foo', $responseData['data']['name']); }
关键注意事项
- 确保测试类继承自
Symfony\Bundle\FrameworkBundle\Test\WebTestCase,这样才能获取到服务容器和测试客户端。 - 如果你的仓库使用了自定义服务ID(而非默认的类全限定名),需要将
set()方法的第一个参数替换为对应的服务ID。 - Mock的方法签名必须和真实仓库完全一致,比如
findOneBy接收的是数组参数,验证时要保持匹配。
原代码失效原因
Symfony的WebTestCase启动客户端时会构建完整的服务容器,控制器依赖的仓库会从容器中获取。你之前仅创建了Mock但未替换容器内的实例,控制器自然会使用真实仓库连接数据库,导致Mock的调用次数验证不通过。
内容的提问来源于stack exchange,提问作者GluePear
相关产品推荐
相关产品推荐

