What you mentioned is sort of (*not entirely*) something I prefer -
minimizing "controller"'s code and delegate to a controller helper, as some
controller's code is reusable. In my Symfony 1 project that uses DI (when
it's still 5.2-supported), I had sort of done this by introducing an extra
layer: sfAction -> ControllerHelper (service in DI) -> *Managers/*Factories
(services in DI). My sfAction code was pretty slim (but sometimes still came
with some personalized form logics, which of course could be moved to the
ControllerHelper).

Anyway, back to the point about registering it as a service - I actually
don't quite like the idea of calling it "Service" in DI nor I like it to be
called "Bean" in Spring, but they are just named. The Spring's annotation
@Component sounds more accurate. To register it as a component? I don't see
any problems and the chance of reusing controller's functions/code really
depends on the nature of the project itself, but I will surely be doing that
because I always prefer to let the container to manage as many components as
it can. :)

The choice of mock/unit tests vs. functional/integration tests? I am a pro
unit test person as I hate slow context setup and I want quicker build, as
long as the integration points are well tested, I will always minimize
writing functional and integration tests.

Yuen-Chi Lian | www.yclian.com
"I do not seek; I find." - Pablo Picasso



On Thu, Sep 23, 2010 at 8:48 AM, Bulat Shakirzyanov <[email protected]>wrote:

> Dear Symfony2 Developers,
>
> After some time working with Symfony2 I am very grateful for the framework.
> It has a very solid foundation and simple a joy to work with.
> Everything uses the provided DIC component, which removes the pain of
> framework setup and wiring of domain specific services.
> However Controllers and Commands in Symfony2 are not quite like that.
> They have access to the container instance, so they can get any service
> that you might need, but it makes the api lie and controllers hardly
> testable.
> There is the web test case that let's you execute complete requests and
> validate the outputs - sort of black box testing, but no support for
> isolated unit tests.
> In order to unit test something you either need to initialize the Kernel or
> initialize local DIC and add all necessary services to it, passing the DIC
> to your controller instance for testing.
> Now since controllers are very lightweight classes, that don't need
> anything but DIC to function, I propose to make them services and let DIC
> handle the wiring.
> In that case in your unit tests you can do:
>
> <?php
> //...
> $dm = $this->getMockDocumentManager();
>
> $dm->expects($this->once())
>
>     ->method('find')
>
>     ->with('User')
>
>     ->will($this->returnValue(array()))
>
> ;
>
> $templating = $this->getMockTemplateEngine();
>
> $templating->expects($this->once())
>
>     ->method('render')
>
>     ->with('UserBundle:User:index', array('users' => array()))
>
>     ->will($this->returnValue('no users'))
>
> ;
> $controller = new UserController();
>
> $controller->setDocumentManager($dm);
>
> $controller->setTemplating($templating);
>
>
> $this->assertEquals('no users', $controller->indexAction());
>
>
> Note that now looking at this example we don't test the outcomes, but we
> test expected interaction, by mocking the necessary methods.
> This should also be much faster that booting up the Kernel.
>
> A perfectly valid question at this point is how do we do the routing, and I
> came up with the following possibilities.
>
> *XML*:
>
> <?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 
> http://www.symfony-project.org/schema/routing/routing-1.0.xsd";>
>
>
>   <route id="_internal" pattern="/:controller/:path.:_format">
>
>     <default key="_controller">user_controller</default>
>
>     <default key="_action">index</default>
>
>   </route>
> </routes>
>
> *
> *
> *
> *
> *YAML*:
>
> user_index:
>
>   pattern: /users.:_format
>
>   defaults: { _controller: 'user_controller', _action: 'index' }
>
> *
> *
> *
> *
> *PHP*:
>
> <?php
> $routes = new RouteCollection();
>
> $routes->add('user_index', new Route('/users.:_format', array(
>
>     '_controller' => 'user_controller',
>
>     '_action'     => 'index',
>
> )));
> return $routes;
>
>
> After or before your routes are specified, you register your controller
> with DIC.
>
> <?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 
> http://www.symfony-project.org/schema/dic/services/services-1.0.xsd";>
>
>
>     <services>
>         <service id="user_controller" 
> class="UserBundle\Controller\UserController">
>
>             <call method="setDocumentManager" />
>
>                 <argument type="service" 
> id="doctrine.odm.mongodb.document_manager" />
>
>             </call>
>             <call method="setTemplating" />
>
>                 <argument type="service" id="templating" />
>
>             </call>
>         </service>
>     </services>
> </container>
>
>
> Unit testing and dependency injection is all about separating the wiring
> and setup of objects from the business logic, allowing you to instantiate
> small portions of your system on demand for testing.
> It shouldn't be hard to implement, but would save a lot of testing
> problems, and potentially, we wouldn't even need the notion of Controller
> (except for the convention), since now any service could serve our requests,
> bringing us closer to re-usability and composition techniques, that OO is
> promoting.
>
> Thoughts?
>
> --
> If you want to report a vulnerability issue on symfony, please send it to
> security at symfony-project.com
>
> You received this message because you are subscribed to the Google
> Groups "symfony developers" group.
> To post to this group, send email to [email protected]
> To unsubscribe from this group, send email to
> [email protected]<symfony-devs%[email protected]>
> For more options, visit this group at
> http://groups.google.com/group/symfony-devs?hl=en
>

-- 
If you want to report a vulnerability issue on symfony, please send it to 
security at symfony-project.com

You received this message because you are subscribed to the Google
Groups "symfony developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/symfony-devs?hl=en

Reply via email to