I bring to your attention the translation of yesterday's post by one of the Symfony2 developers about the approach to unit testing of controllers in Symfony2. The theme is very relevant for Symfony2 developers. It is also worth noting that the post mentions the result of the discussion on dev-groups about using the controller as a service in 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());Despite the fact that this method is easy to read and understand, it has drawbacks:<?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());
}
}
Note: the controller is now a POPO (plain old PHP object) without a base class that it should extend. Symfony2 doesn’t need anything else to work except the controller class itself.<?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
After completing these steps, you can try this in the browser by typing the URL:your_application/your_front_controller.php/index
Source: https://habr.com/ru/post/105361/
All Articles