Подтвердить что ты не робот

Как я могу unit test контроллер Symfony2?

Я хочу использовать Test Driven Development как можно больше - это отличный способ работы.

Меня беспокоит тот факт, что контроллеры Symfony2 создают и возвращают новый объект Response.

Я хочу иметь возможность unit test изолировать контроллер.

Как вы это делаете?

Является ли ответ на создание контроллера как обычного обычного PHP-объекта, зарегистрировать его как службу и использовать Injection Dependency для передачи в него нового объекта Response (или Response factory)?

4b9b3361

Ответ 1

Обычно ваш контроллер подключает разные объекты и подключает их в правильном порядке. Возможно, он называет репозиторий, читает некоторые объекты и возвращает их через метод рендеринга. Может быть, он называет некоторых других Handlers/Managers, которые делают что-то.

Это означает, что контроллер является компонентом высокого уровня. Чаще всего это указывает на то, что функциональные тесты в порядке, а не модульные тесты. Вы не должны стремиться получать 100% -ный охват кода с помощью модульных тестов. Возможно, вы можете так думать: если вы unit test все, что вызывает контроллер (модель, валидация, форма, репозиторий), что может пойти не так? В большинстве случаев это то, что вы наблюдаете только при использовании всех реальных классов, участвующих в процессе производства.

Я хочу также отметить, что TDD не означает, что все должно быть проверено на единицу. Это нормально, чтобы иметь некоторые функциональные тесты для кода высокого уровня. Как сказано, если вы тестируете низкоуровневые компоненты с помощью модульных тестов, вы должны только проверить, как они работают вместе, что вы не можете тестировать с помощью mocks, потому что вы скажете, что mocks имеет значение возврата.

Если ваш контроллер делает больше, чем подключать части системы вместе, вы должны подумать о том, чтобы реорганизовать материал на более низкоуровневые классы, которые вы можете тестировать с помощью модульных тестов.

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

Если вы боретесь с функциональными тестами, вы можете прочитать следующее:

Ответ 2

Используйте mocks для выделения моделей и других объектов из логики метода основного контроллера, см. http://www.phpunit.de/manual/3.7/en/test-doubles.html#test-doubles.mock-objects

Я думаю, что в более старых версиях вы могли бы издеваться над целым классом, но с последним phpunit 3.6.10, который у меня есть, похоже, не работает. Поэтому, я думаю, вы остаетесь с шаблоном инъекции depency

class objss{
    function ss(){
        $x = new zz();
        var_dump($x->z());
    }
}



class MoTest extends PHPUnit_Framework_TestCase{
    public function setUp(){

    }

    public function testA(){
        $class = $this->getMock('zzMock', array('z'), array(), 'zz');
        $class->expects($this->any())->method('z')->will($this->returnValue('2'));

        $obj = new objss();
        $this->assertEquals('2', $obj->ss());
    }
}

Ответ 3

Тестирование устройств

Восстановите свои контроллеры как сервисы: http://symfony.com/doc/current/cookbook/controller/service.html

Тогда вы можете легко unit test их.

Функциональное тестирование

Конечно (как уже упоминалось другими) вы можете использовать WebTestCase, как описано здесь: http://symfony.com/doc/current/book/testing.html#functional-tests

Ответ 4

Льюис - Я думал, что приеду сюда. В приведенном выше подходе вы копируете лучшую часть своей логики действий в своих тестах. В этом нет ничего плохого, многие фреймворки (особенно RSPEC в Rails) на самом деле предлагают вам выполнять как модульные тесты на объектах Controller, так и функциональные тесты. Однако, учитывая ваш пример, я думаю, что пропустил unit test и подойду для функционального подхода.

Точка теста, на мой взгляд, заключается в создании изолированной среды, запуска теста и проверки на наличие побочных эффектов и прямой результат. Если вы дойдете до точки, где большая часть вашего теста изолирует метод, то это, вероятно, время либо для другого подхода к тестированию, либо для другого подхода к написанию вашего класса. Учитывая, что это контроллер, и по своей природе они склеивают разные части стека, я бы создал вашу песочницу дальше по стеку. В частности, я бы использовал такой подход:

https://github.com/PolishSymfonyCommunity/SymfonyMockerContainer

Отлично работает для меня:)