2013-11-01 5 views
19

У меня есть служба symfony, которая использует redis-соединение в некоторых методах, но не во всех методах.Как издеваться над сервисом Symfony 2 в функциональном тесте?

class ServiceA 
{ 
    private $redis; 

    public function __construct($redis) 
    { 
     $this->redis = $redis; 
    } 

    public function getRequest($param1, $param2) 
    { 
    $result = $param1+ $param2; 
     return $request; 
    } 

    .. other methods which use $redis connection 
} 

Я пишу функциональный тест для кода, которые используют только GetRequest метод (этот метод не требует REDIS соединения), но как конструктор принимает соединение в качестве аргумента, когда я запускаю тест он пытался соединить Redis сервера ,

Как написать mock-сервис, который вообще не использует соединение redis и игнорировать исходный конструктор.

Я стараюсь, чтобы подход, упомянутый ниже, но не удался. Он по-прежнему пытается связать redis, хотя я отключил исходный конструктор.

http://blog.lyrixx.info/2013/04/12/symfony2-how-to-mock-services-during-functional-tests.html

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

static::$kernel->getContainer()->set('my_bundle.service.a', $serviceA); 

ответ

45

После создания ServiceA издеваетесь, вам нужно передать его в контейнер клиента (а не один из ядра-х, потому что объект клиент строит свое собственное ядро). Попробуйте следующее:

$client = self::createClient(); 

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

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

Обратите внимание, что вы должны вводить эту издеваемую службу каждый раз, когда вы делаете запрос. Это связано с тем, что клиент перестраивает ядро ​​между двумя запросами.

+1

Emphase на «вы должны передать его в контейнер клиента (а не одного из ядра)». – magnetik

+2

Does '$ client-> getContainer() -> set ('my_bundle.service.a', $ serviceA)' подразумевать, что '$ container-> get()' больше не будет создавать службу? Мы хотим «переопределить» службу, но все же хотим, чтобы контейнер впоследствии вводил службы в свои зависимости. – Rvanlaak

+1

Нет, это не будет создавать экземпляр службы больше, как только вы установите объект методом «set». Вам нужно позаботиться об этом самостоятельно. – Cyprian

0

Вы пробовали?

$serviceA = $this->getMock('ServiceA', array('getRequest'), array(), '', false); 
5

Вы не должны высмеивать свой испытанный класс, вы должны высмеять класс Redis и ввести его.

Если Redis не используется для этого теста, вам даже не нужно настраивать макет.

$redis = $this->getMockBuilder('Redis')->disableOriginalConstructor()->getMock(); 
$serviceA = new ServiceA($redis); 
Смежные вопросы