Search code examples
phpsymfonyphpunitsymfony-3.2

Symfony3 testing the redirectToRoute() method with phpunit


I am trying to make one of the most simplest (I think) functional test by PHPUnit for a Symfony3 controller.

My controller code is just a redirect:

class DefaultController extends Controller
{
    public function indexAction()
    {
        return $this->redirectToRoute('admin_dashboard', array(), 301);
    }
}

and my test function is as follows:

class DefaultControllerTest extends WebTestCase
{
    public function testIndex()
    {
        $client = static::createClient(array(), array(
            'HTTP_HOST' => 'www.admin.dev',
        ));

        $client->request('GET', '/');
        $client->followRedirect();
        $this->assertTrue($client->getResponse()->isRedirect('/dashboard/'));
    }
}

The error that I get here is as follows:

LogicException: The request was not redirected

Also some of the results that I get for some values are as follows:

$client->getRequest()->getUri() -> "http://www.admin.dev/"
$client->getResponse()->getStatusCode() -> 404
$client->getResponse() instanceof RedirectResponse -> false
$client->getResponse()->headers->get('location') -> null

A little more background for this issue:

  • I have multiple domains pointing to this same project
  • The bundle is only loaded when the relative domain is asked for.

For example:

www.admin.dev -> admin bundle
www.admin2.dev -> admin2 bundle
www.admin3.dev -> admin3 bundle

Any ideas what am I doing wrong that I am stuck with this simple problem?

My routing configuration is:

homepage:
    host: "www.%domain%"
    path:     /
    defaults: { _controller: MyBundle:Default:index}

admin_dashboard:
    host: "www.%domain%"
    prefix:   /dashboard
    path:     /
    defaults: { _controller: MyBundle:Dashboard:index}

And

%domain% is a parameter in the parameter file. The value is 'admin.dev'

Solution

  • At last I solved it. Thanks to ccKep for pointing me to the right direction. All my domains had their own environment and hence, all the routes were not available. Like:

    www.admin.dev -> loads routes for only admin bundle
    www.admin2.dev -> loads routes for only admin2 bundle
    www.admin3.dev -> loads routes for only admin3 bundle
    

    So, to solve the problem I first debug the routes for the 'test' environment (as this environment is responsible for the tests) by calling:

    php bin/console debug:router --env=test
    

    and found that it only includes the generic routes and not the domain specific routes. So, to have the routes to be included in my test environment, I included the routing information of my domain into my test routing file.

    For those who are still curious about my strange configuration:

    I have 3 domains pointing to my project:

    www.admin.dev
    www.admin2.dev
    www.admin3.dev
    

    Depending on this domains, the bundles are loaded as:

    www.admin.dev  -> loads MyAdminBundle
    www.admin2.dev -> loads MyAdmin2Bundle
    www.admin3.dev -> loads MyAdmin3Bundle
    

    Each of my domains have 2 environment of them as:

    www.admin.dev  -> dev_admin  and prod_admin
    www.admin2.dev -> dev_admin2 and prod_admin2
    www.admin3.dev -> dev_admin3 and prod_admin3
    

    And based on these domains and their environment, I have my configuration and routing defined so that when www.domain.dev is called, it uses the configuration, routing and the respective bundle based on its environment and nothing of the MyAdmin2Bundle or MyAdmin3Bundle or any of their routes or configuration.

    To make it a bit more clear, I have configuration files like:

    config.yml
    config_dev.yml
    config_dev_domain.yml
    config_dev_domain2.yml
    config_dev_domain3.yml
    config_prod.yml
    config_prod_domain.yml
    config_prod_domain2.yml
    config_prod_domain3.yml
    config_test.yml
    

    And routing files like:

    routing.yml
    routing_dev.yml
    routing_dev_domain.yml
    routing_dev_domain2.yml
    routing_dev_domain3.yml
    routing_prod.yml
    routing_prod_domain.yml
    routing_prod_domain2.yml
    routing_prod_domain3.yml
    routing_test.yml
    

    Now what I have done it, just included the routing files of domain, domain2 and domain3 into the routing_test.yml. I hope this is enough to understand.