In todays web industry, developers should strive to become ‘Software Engineers’ and behave like professionals.  In order to do this developers all over the world have been adopting TDD (Test Driven Development), which in simple terms is the practice of writing unit tests before writing application code.  We will talk more about TDD in an upcoming post, but for now we need to know how to make our code testable.

Symfony 2

Screen Shot 2014-02-09 at 16.13.26

When we read the official Symfony 2 documentation, they often recommend extending a base controller or some other class to inherit some in-built behaviour.  When writing testable, clean code, it is recommended to favour composition over inheritance, and it is also recommended to favour composition to allow our code to be easier to test as we do not wish to test code that we have not written.

When using Symfony 2 we can access a dependancy injection container which comes with the framework.  This is very good news as this allows us the inject dependancies into the constructors of our classes (including the controllers).  In order to do this we must configure the container.  The following examples will be in XML (but can also be accomplished in  YML), and we will be configuring the container in the standard symfony way, using the services.xml file located within the bundle in question under Resources\config\services.xml

We must define our controller class as a parameter.  We do this via the parameters section of the XML:

<parameters><parameter key=”category.controller.class”>Beanbag\CoreBundle\Controller\CategoryController</parameter></parameters>

Next we can define our service within the services section like so:

<service id=”controllers.category” class=”%category.controller.class%”>
            <argument type=”service” id=”beanbag.category.service” />
</service>

By using the naming convention controllers.category for the service id, we are telling Symfony 2 that this service is a controller.  As you can see we are injecting the beanbag.cateogry.service into the category controllers constructor (which in this case might be the domain model).

Within our controller we can now define our constructor like so:

private $categoryService;

public function __construct(CategoryService $categoryService)
{
$this->categoryService = $categoryService;
}

And our actions might look like so:

public function getCategoriesAction()
{
return $this->categoryService->findAll();
}

It is very easy to now test our controllers as we can now mock the category service, adding any test cases we need.