Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony unit testing & the container

When unit testing in Symfony 2, the controller I'm testing does not receive the service container causing the test to fail with the good old Call to a member function get() on a non-object

I can't use $this->forward from the testing controller as it also does not have the service container.

I found this reference but it seems as though I would be using it for the wrong reason, has anyone had any experience with this?

http://symfony.com/doc/current/book/testing.html#accessing-the-container

Edit: Here is my test:

<?php

namespace HvH\ClientsBundle\Tests\Controller;

use HvH\ClientsBundle\Controller\ClientsController;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\HeaderBag;
use Symfony\Component\HttpFoundation\Session;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class ClientsControllerTest extends WebTestCase
{

    public function testGetClientsAction()
    {

        $client = static::createClient();
        $container = $client->getContainer();
        $session = $container->get('session');
        $session->set('key', 'value');
        $session->save();

        $request = new Request;
        $request->create('/clients/123456', 'GET', array(), array(), array(), array(), '');

        $headers['X-Requested-With'] = "XMLHttpRequest";
        $request->headers->add($headers);

        /* This doesn't work */
        /*
        $controller = new Controller;
        $status = $controller->forward( 'HvHClientsBundle:Clients:getClients', array('request' => $request) );        
        */

        $clients_controller = new ClientsController();
        $status = $clients_controller->getClientsAction($request);

        $this->assertEquals(200, $status);
    }

}

Here is the part of the clients controller where it fails

<?php

namespace HvH\ClientsBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use HvH\APIschemaBundle\Controller\Validation;


//FOSRestBundle
use FOS\RestBundle\View\View;

class ClientsController extends Controller
{

    //Query all clients
    public function getClientsAction(Request $request)
    {
        $request_type = $request->headers->get('X-Requested-With');

        if($request_type != 'XMLHttpRequest') {
            return $this->render('HvHDashboardBundle:Dashboard:dashboard.html.twig' );          
        }

        //get any query strings
        $query_strings = $request->query->all();
        $definition = $this->get("service.handler")->definition_handler(__CLASS__, __FUNCTION__);
        //once data has been prepared 
        return $this->get('fos_rest.view_handler')->handle($view);

    }    
}
like image 842
greg Avatar asked Oct 15 '25 15:10

greg


1 Answers

I think the reason the controller isn't getting a container is because you are trying to instantiate and interact with it directly rather than simulating requests using the client (See the section on Functional Tests in the Testing section of the Symfony2 book).

You need something more like this (not sure if the route is correct):

public function testGetClientsAction()
{
    $client = static::createClient();

    $client->request(
        'GET', '/clients/123456', 
        array(), /* request params */ 
        array(), /* files */
        array('X-Requested-With' => "XMLHttpRequest"),
    );

    $this->assertEquals(200, $client->getResponse()->getStatusCode());  
}

Note also, the request() method returns a crawler instance which provides helper methods to verify the content of the response if required.

like image 131
redbirdo Avatar answered Oct 17 '25 08:10

redbirdo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!