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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 20:40:17