在 Symfony 测试中控制依赖关系

Controlling dependencies in Symfony tests

我对我的 Symfony 4.2 应用程序进行了大量边到边测试。我指的是使用测试客户端发出 Web 请求然后对结果进行断言的测试。示例:

public function testPageNotFound() {
    $client = $this->createClient();
    $client->request('GET', 'does-not-exist');
    $this->assertSame(404, $client->getResponse()->getStatusCode());
}

有没有办法在此类测试中更改服务容器中的特定服务?

示例问题:我有通过名为 FileFetcher 的抽象发出 Web 请求的服务。对于我的测试,我希望使用 NullFileFetcher 这样就不会发出真正的 Web 请求。我如何告诉 Symfony 使用这个测试替身?

令人惊讶的是,在主要测试文档中没有关于如何执行此基本测试任务的信息 https://symfony.com/doc/current/testing.html

我尝试的一种方法是在 config/packages/test/services.yaml 中进行配置。这没有用,据我所知,这是由于 Symfony 不允许覆盖 services.yaml,因为它最后加载主 config/services.yamlhttps://symfony.com/doc/current/configuration.html#configuration-environments

最后我想做的就是遵循一些非常基本的测试最佳实践:

  1. 在每个测试方法执行开始时初始化整个环境
  2. 可能更改特定服务和配置,使其远离默认设置
  3. 执行被测代码并对结果进行断言

任何使用 Symfony 执行此操作的代码示例将不胜感激。

您应该能够通过在容器中换出它来覆盖测试中的服务

$this->container->getDefinition('x.x_service')->setSynthetic(true);
$this->container->set('x.x_service', new NullFileFetcher());

文档需要更新:最后一个覆盖之前定义的文件是config/services_test.yaml 那应该可以帮助您解决用例。 参见 https://github.com/symfony/recipes/blob/master/symfony/framework-bundle/4.2/src/Kernel.php#L42