Предлагаю вашему вниманию перевод вчерашнего поста одного из разработчиков Symfony2 о подходе к unit-тестированию контроллеров в Symfony2. Тема очень актуальна для Symfony2 разработчиков. Также стоит отметить, что в посте упоминается результат дискуссии на dev-groups об использовании контроллера в роли сервиса в Symfony2.<?php
$client = $this->createClient();
$client->request('GET', '/index');
$response = $client->getResponse();
$this->assertEquals(200, $response->getStatusCode());
$this->assertRegExp('/<h1>My Cool Website<\/h1>/', $response->getContent());Несмотря на то, что этот метод легко читаем и понятен, у него есть недостатки:<?php
namespace Company\ApplicationBundle\Tests\Controller;
use Company\ApplicationBundle\Controller\IndexController;
class IndexControllerTest extends \PHPUnit_Framework_TestCase
{
//...
public function testIndexAction()
{
$templating = $this->getMock('Symfony\Bundle\FrameworkBundle\Templating\Engine');
$templating->expects($this->once())
->method('render')
->with('Application:Index:index')
->will($this->returnValue('success'))
;
$controller = new IndexController();
$controller->setTemplating($templating);
$this->assertEquals('success', $controller->indexAction());
}
}
Замечание: котроллер — сейчас это POPO (plain old PHP object) без базового класса, который он должен расширять. Symfony2 для работы ничего более не нужно кроме класса контроллера как такового для его работы.<?php
namespace Company\ApplicationBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Templating\Engine;
class IndexController
{
/**
* @var Symfony\Bundle\FrameworkBundle\Templating\Engine
*/
private $templating;
/**
* @param Symfony\Bundle\FrameworkBundle\Templating\Engine $templating
*/
public function setTemplating(Engine $templating)
{
$this->templating = $templating;
}
/**
* @return Symfony\Component\HttpFoundation\Response
*/
public function indexAction()
{
return $this->templating->render('ApplicationBundle:Index:index');
}
}<?xml version="1.0" ?>
<container xmlns="http://www.symfony-project.org/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.symfony-project.org/schema/dic/services www.symfony-project.org/schema/dic/services/services-1.0.xsd">
<services>
<service id="index_controller" class="Company\ApplicationBundle\Controller\IndexController">
<call method="setTemplating" />
<argument type="service" id="templating" />
</call>
</service>
</services>
</container><?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://www.symfony-project.org/schema/routing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.symfony-project.org/schema/routing www.symfony-project.org/schema/routing/routing-1.0.xsd">
<route id="index" pattern="/index">
<default key="_controller">index_controller:indexAction</default>
</route>
</routes><?php
namespace Company\ApplicationBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
class ApplicationBundle extends Bundle {
public function registerExtensions(ContainerBuilder $container) {
parent::registerExtensions($container);
// register controllers
$loader = new XmlFileLoader($container);
$loader->load(__DIR__.'/Resources/config/controllers.xml');
}
}Company
| - ApplicationBundle
| | - Controller
| | | - IndexController.php
| | - Resources
| | | - config
| | | | - controller_routing.xml
| | | | - controllers.xml
| | | - views
| | | | - Index
| | | | | - index.php
| | - ApplicationBundle.php
После выполнения этих шагов, вы можете попробовать это в браузере, набрав URL: your_application/your_front_controller.php/index
Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.
комментарии (25)