symfony2 unit test

how tu simulate a request without call a controller? This article give a solution even his basic idea is to fast the controller unit test. For example, if we need to test a service which is called by a controller. In the service we have some parmeters from the request, or have a request as parameter, so we need to generate the container before test this service. But the normal way of symfony2 unit test you need to generate a client and then send them to controller, so we need to find a way directly inject our container to the service.

http://leftnode.com/entry/faster-symfony2-tests.html  see this.


namespace Acme\DemoBundle\Tests\Unit\Controller;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\HttpFoundation\Request;

class ControllerTest extends WebTestCase
{

    public function testControllerAction()
    {
        $client = static::createClient();
        $container = $client->getKernel()
            ->getContainer();

        $request = new Request;
        $request->headers->set('Accept', 'application/json');
        $request->server->set('REMOTE_ADDR', '127.0.0.1');

        $container->set('request', $request);

        $controller = new \Acme\DemoBundle\Controller\PageController;
        $controller->setContainer($this->container);

        $response = $controller->readAction();

        $this->assertEquals(200, $response->getStatusCode());
        $this->assertRegExp('/foo/i', $response->getContent());
    }

}
or you can just wirte a base unittest case:

namespace Acme\DemoBundle\Tests\Unit\Controller;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\HttpFoundation\Request;

class BaseControllerTestCase extends WebTestCase
{

    protected $client = null;
    protected $container = null;

    public function setUp()
    {
        $this->client = static::createClient();

        $this->container = $this->client
            ->getKernel()
            ->getContainer();
    }

    /**
     * Builds a Controller object and the request to satisfy it. Attaches the request
     * to the object and to the container.
     *
     * @param string The full path to the Controller class.
     * @param array An array of parameters to pass into the request.
     * @return Controller The built Controller object.
     */
    protected function createController($controllerClass,
        array $parameters=array(), array $query=array())
    {
        $request = $this->createWebRequest();
        $request->request->add($parameters);
        $request->query->add($query);

        $this->container
            ->set('request', $request);

        $controller = new $controllerClass;
        $controller->setContainer($this->container);

        return($controller);
    }

    /**
     * Creates a new Request object and hydrates it with the proper values to make
     * a valid web request.
     *
     * @return Request The hydrated Request object.
     */
    protected function createWebRequest()
    {
        $request = new Request;
        $request->headers->set('Accept', 'application/json');
        $request->server->set('REMOTE_ADDR', '127.0.0.1');

        return($request);
    }

}
and then use it like this:
namespace Acme\DemoBundle\Tests\Unit\Controller;

use Acme\DemoBundle\Tests\Unit\Controller\BaseControllerTestCase;

class PageControllerTest extends BaseControllerTestCase
{

    public function testReadAction()
    {
        $controllerName = 'Acme\DemoBundle\Controller\PageController';
        $controller = $this->createController($controllerName);

        $response = $controller->readAction();

        $this->assertEquals(200, $response->getStatusCode());
        $this->assertRegExp('/foo/i', $response->getContent());
    }

}
but with this we can not use symfony2 profiler.

评论

热门帖子