使用symfony di容器

时间:2017-11-11 09:02:22

标签: php symfony phpunit

问题摘要

是否可以在我的测试用例中向symfony di容器注入存根/模拟以模拟不同的外部api响应?

  • 测试我的应用程序发送电子邮件,如果api返回错误(我想为我的http客户端类注入一个返回HTTP 500的存根)
  • 测试我的应用程序使用2个不同的API作为源返回正确的结果(我想将两个HTTP客户端作为存根注入特定的结果体)

详情

我想为使用symfony di容器的silex应用程序编写功能测试。该应用程序使用多个API作为后端来填充客户端请求。

代码将一个抽象的http客户端注入api客户端,我可以在其中注入一个http api客户端存根。

class AwesomeApiClient
   __construct(MyHttpClient $httpClient);

class MyApiHttpClient

这对单元测试非常有用。

现在我想写功能测试。 我扩展了silex WebTestCase并实现了应用程序初始化。 使用symfony di容器注入MyApiHttpClient。

现在我想做这样的事情:

# symfony di container does not allow this
$this->getDiContainer()->set('my_http_client', $myHttpClientStubInstance);

我想在每个测试中配置我的存根,这样我就可以测试同一请求的不同(例如错误,成功)响应。

我尝试过的事情:

在运行时使用setter注入

$his->getDiContainer()->get('MyApiClient')->setHttpClient($myMock);

每次调用get方法时,DiContainer都会返回一个新实例。这确实是绝对有意义的。所以这不起作用。

覆盖di容器中的http客户端

$this->getDiContainer->set('MyHttpClient', $myHttpClientStub);

不起作用,因为symfony不允许在运行时更改定义。它似乎也采用了定义,而不是实例。

PHP-VCR

在我的生产代码中进行一些更改,因为它会在我的curl标头回调中弄乱HTTP标头。不适用于其他服务(rabbitmq ......)

1 个答案:

答案 0 :(得分:1)

根据this,应该可以在DI容器中设置mock。

$client = self::createClient();

$serviceA = $this->getMockBuilder('ServiceA')
    ->disableOriginalConstructor()
    ->getMock();

$client->getContainer()->set('my_bundle.service.a', $serviceA);