2015-06-22 51 views
1

我正在为控制器编写功能测试。 它使用一个类来从第三方网站导入一些数据,并且为此我写了一个我在Symfony中使用的类将其设置为服务。Symfony2:模拟服务设置在容器中但未被控制器使用(它仍然使用原始服务)

现在,在我的功能测试中,我想用一个嘲弄的替代该服务,将其设置在容器中,并在我的功能测试中使用它。

所以我的代码如下:

// Mock the ImportDataManager and substitute it in the services container 
    $mockDataImportManager = $this->getMockBuilder('\AppBundle\Manager\DataImportManager')->disableOriginalConstructor()->getMock(); 
    $client->getContainer()->set('shq.manager.DataImport', $mockDataImportManager); 

    $client->submit($form); 
    $crawler = $client->followRedirect(); 

正如我知道之间的每个请求的客户端重新启动的内核,我必须重新设置嘲笑类,我调用到$紧接在之前设置的模拟客户端 - >提交。

但是,这种方法似乎不适合我,控制器仍然继续使用服务的真实版本,而不是嘲笑的。

如何使用模拟类避免在功能测试期间调用远程网站?

如果我转储集嘲笑服务,我可以看到它设置正确:

dump($client->getContainer()->get('shq.manager.DataImport'));die; 

回报

.SetUpControllerTest.php on line 145: 
Mock_DataImportManager_d2bab1e7 {#4807 
    -__phpunit_invocationMocker: null 
    -__phpunit_originalObject: null 
    -em: null 
    -remotes: null 
    -tokenGenerator: null 
    -passwordEncoder: null 
    -userManager: null 
} 

但它$form->submit($form)通话中未使用的,相反,是使用原始服务。

UPDATE 继续寻找解决的办法,我降落在this GitHub page从Symfony的项目中,用户请求解决我同样的问题。 第二个调用不使用他的类的模拟/替换版本,而是使用原始版本。

这是正确的行为?那么,是否真的不能在第二次调用客户端时修改服务容器?

回答

0

然而,我不明白为什么服务没有在容器中被替代,我没有真正的解决方案。

无论如何,我发现某种解决方法,实际上更正确的解决方案(也如果它仍然不清楚为什么服务没有被取代,这是我想解决的好奇心 - 也许是因为$客户端 - >提交()方法使用POST方法?)。

我的解决方法是一个简单的测试双。

我在AppBundle/Tests/TestDouble中创建了一个新类,并将其命名为DataImportManagerTestDouble.php

它包含由控制器所使用的独特的方法:在所述

services: 
    shq.manager.DataImport: 
     class: AppBundle\Tests\TestDouble\DataImportManagerTestDouble 

这样,:

namespace AppBundle\Tests\TestDouble; 

use AppBundle\Entity\User; 

class DataImportManagerTestDouble 
{ 
    public function importData(User $user) 
    { 
     return true; 
    } 
} 

然后,我实例它在config_test.ymlapp/config/config_test.yml)文件以下面的方式测试,并且只有在测试期间,作为服务加载的类是TestDouble,而不是原来的。 所以测试通过,我(相对)高兴。目前来说,至少。