【问题标题】:Symfony 3.3 service mocks for functional tests用于功能测试的 Symfony 3.3 服务模拟
【发布时间】:2017-06-02 07:20:51
【问题描述】:

在 Symfony 3.3 之前,允许在容器上设置模拟服务。现在在 3.3 中会抛出弃用警告,因为该服务已经预定义。

覆盖容器中现有或预定义服务以设置模拟服务以进行功能测试的新标准方法是什么?

例如在我们的例子中,我们设置了一个新的实体管理器,其中包含一个新的模拟连接,指向一个克隆的数据库进行测试。

$container->set('doctrine.orm.entity_manager', $testEm);

设置“doctrine.orm.entity_manager”预定义服务自 Symfony 3.3 起已弃用,Symfony 4.0 不再支持。

【问题讨论】:

  • 当您可以更改测试环境配置时,为什么需要模拟 entity_manager 进行测试?
  • 这对我们来说还不够。我们有各种数据库功能测试,每个测试都会收到一个新的克隆数据库来处理。因此,对于每个测试类甚至测试方法都必须可以模拟实体管理器。
  • 使用固定装置和 setUp() 和 tearDown() 等,有更简单和更好的方法来解决这个问题,而不是实际“克隆”到实际的单独数据库中
  • EntityManager 只是一个例子,我们只是需要模拟一个深度注入的服务,为此我们需要另一种方式。如果没有其他方法,我们将扩展 Container 并手动设置我们的模拟服务。

标签: symfony functional-testing


【解决方案1】:

几天前我遇到了同样的问题,我写了一个库来欺骗 Symfony 的 DIC:https://github.com/TiMESPLiNTER/proxy-mock

这个想法是用原始服务类中的“代理”覆盖 config_test.yml 中的服务,它将所有调用重定向到一个模拟,然后可以在测试用例中动态设置。

# config_test.yml
services:
    timesplinter.proxy_mock.factory:
        class: timesplinter\ProxyMock\ProxyMockFactory

    acme.api.client:
        factory: 'timesplinter.proxy_mock.factory:create'
        arguments: ['Acme\AppBunde\Services\ApiClient']

这将覆盖在原始服务中定义的服务。(xml|yml) 使用它的代理。

在测试用例中,您可以执行以下操作:

// Your container aware test case (this exmaple is for PHPUnit)
$mock = $this->getMockBuilder(ApiClient::class)->disableOriginalConstructor()->getMock();

$container->set('acme.api.client')->setMock($mock);

这样,您的测试将针对您使用 setMock() 方法提供的模拟运行。

该库非常新,因此可能缺少某些功能。如果您使用它并遗漏了某些内容,请提供具有所需功能的拉取请求。

【讨论】:

    猜你喜欢
    • 2020-08-19
    • 2013-11-12
    • 1970-01-01
    • 1970-01-01
    • 2019-04-13
    • 2021-03-28
    • 2017-10-27
    • 2020-04-11
    • 1970-01-01
    相关资源
    最近更新 更多