2017-02-01 7 views
3

Мы используем PHPUnit для тестирования частей нашего приложения. В некоторых тестах мы хотим изменить значение параметра или переопределить службу (но только для этого теста, не для всех тестов).Как установить параметры или службы в Symfony в тестах PHPUnit?

Каков рекомендуемый способ настройки контейнера Symfony на лету в тестах?

Проблема, с которой мы столкнулись, заключается в том, что контейнер не перекомпилируется, когда конфигурация установлена ​​«на лету» (поскольку она только перекомпилирует себя, когда файлы были изменены).

+0

вы могли бы попробовать что-то вроде '$ this-> client- > getContainer() -> set ('application.facebook_guzzle', $ client); 'иногда это не работает ... – Matteo

+2

@Matteo это не работает с параметрами (потому что контейнер скомпилирован) –

ответ

3

Это, как мы переходим сейчас:

class TestKernel extends \AppKernel 
{ 
    public function __construct(\Closure $containerConfigurator, $environment = 'test', $debug = false) 
    { 
     $this->containerConfigurator = $containerConfigurator; 

     parent::__construct($environment, $debug); 
    } 

    public function registerContainerConfiguration(LoaderInterface $loader) 
    { 
     parent::registerContainerConfiguration($loader); 
     $loader->load($this->containerConfigurator); 
    } 

    /** 
    * Override the parent method to force recompiling the container. 
    * For performance reasons the container is also not dumped to disk. 
    */ 
    protected function initializeContainer() 
    { 
     $this->container = $this->buildContainer(); 
     $this->container->compile(); 
     $this->container->set('kernel', $this); 
    } 
} 

Затем мы добавили этот метод в нашем базовом тестовом PHPUnit классе:

/** 
* Rebuilds the container with custom container configuration. 
* 
* @param \Closure $containerConfigurator Closure that takes the ContainerBuilder and configures it. 
* 
* Example: 
* 
*  $this->rebuildContainer(function (ContainerBuilder $container) { 
*   $container->setParameter('foo', 'bar'); 
*  }); 
*/ 
public function rebuildContainer(\Closure $containerConfigurator) : ContainerInterface 
{ 
    if ($this->kernel) { 
     $this->kernel->shutdown(); 
     $this->kernel = null; 
     $this->container = null; 
    } 

    $this->kernel = new TestKernel($containerConfigurator); 
    $this->kernel->boot(); 
    $this->container = $this->kernel->getContainer(); 

    return $this->container; 
} 
0

Вы не тестируете контейнер или конфигурацию в модульных тестах. В модульных тестах цель состоит в проверке блоков, инкапсулированных без полного стека приложений.

Для функциональных тестов рекомендуется способ, чтобы изменить его в унаследованной конфигурации под app/config/config_test.yml

Все значения из config_dev.yml могут быть перекрыты там.

+0

И как это помощь по тестированию на основе тестирования? – Cerad

+0

Для модульного тестирования вы не должны полностью полагаться на Контейнер/Конфигурация. Для функциональных тестов с Symfony вы также используете PhpUnit. Это правильный способ сделать это: https://symfony.com/doc/current/testing.html#functional-tests – mblaettermann

+1

Вы даже прочитали вопрос? Тот факт, что PHPunit используется, не подразумевает единичный тест. И ваше предлагаемое решение - вздор. Вниз проголосовали соответственно. – Cerad

-1

$ serializer = new \ JMS \ Serializer \ SerializerBuilder(); $ container-> set ('jms_serializer', $ serializer :: create() -> build());

+0

См. Комментарий, который я разместил. Также это не работает, если служба уже введена перед вызовом 'set()'. –