2017-06-02 131 views
8

在Symfony 3.3之前,允许将模拟服务设置到容器上。现在使用3.3,抛弃了警告,因为服务已经预先定义好了。Symfony 3.3用于功能测试的服务模拟

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

E.g.在我们的例子中,我们设置了一个新的实体管理器,并新建了一个指向克隆数据库的模拟连接进行测试。

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

设置“doctrine.orm.entity_manager”预定义的服务,因为Symfony的3.3已被弃用,不会在Symfony的4.0不再支持。

+0

为什么你需要为了测试目的而模拟entity_manager,何时才能改变测试环境配置? – sensorario

+0

这对我们来说还不够。我们有各种各样的数据库功能测试,每个测试都会收到一个新的克隆数据库。所以嘲笑实体管理器必须可能用于每个测试类,甚至测试方法。 –

+0

使用fixtures和setUp()和tearDown()等,有更简单和更好的方法去实现这个,而不是实际上'克隆'到一个实际的单独数据库中 –

回答

0

我只是前几天有同样的问题,我写了一个库,以欺骗的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()方法模拟。

该库是非常新的,因此某些功能可能会丢失。如果您使用它并错过了某些内容,请提供具有所需功能的拉取请求。