Search code examples
testingsymfonybundlefunctional-testing

Specify a configuration when WebTestCase is used for functional testing a bundle?


What I'm trying to do is to functional test my bundle (a reusable one). More in deep:

  • Create a request to a given url /my/url
  • Check that MyParamConverter is invoked and converts the request into an instance of MyObject
  • Check that the controller throws my.event

As per documentation I should extend Symfony\Bundle\FrameworkBundle\Test\WebTestCase and create a new client:

    $client  = static::createClient();
    $crawler = $client->request('GET', '/my/url');

Doing it this way, which bundles are loaded? How can I specify a configuration file to use in the environment (assuming it's default to test)?

EDIT: Ok, time to explain better my question. I'm wring a reusable bundle, say AcmeMessagingBundle. Now I want to functional test it. Scenario is a call to /my/url:

public function testReceiveApiRoute()
{
    $client = $this->createClient();

    /** @var $route \Symfony\Component\Routing\Route */
    $route  = $client->getContainer()->get('router')
        ->getRouteCollection()->get('acme_messaging_receive');

    $this->assertNotNull($route);
    $this->assertEquals('POST', $route->getRequirement('_method'));
    $this->assertEquals('acme_messaging.controller.api:receive',
        $route->getDefault('_controller'));
}

/**
 * @depends testReceiveApiRoute
 */
public funcion testReceiveApiWorkflow()
{
    $client = $this->createClient();

    // Make a POST request
    $request = Request::create('/my/route', 'POST', array(
        'a' => 'value'
    ));

    // Request is convered in MyObject instance and that my.event is fired
}

With this test, app/config_test.yml is loaded (say "main config file"). Question is:

Shouldn't test be "isolated", meaning not using the main config file? What if my bundle is tested by another person with an empty app/config_test.yml? Test would fail...

The test will fail also with a prefixed route. If routing.xml from AcmeMessagingBundle is imported with a prefix, testReceiveApiWorkflow is going to fail!


Solution

  • Using WebTestCase will use your own AppKernel with the test environment.

    You can either add a new env to your app, and use it in the WebTestCase like this:

    $client = static::createClient(array('environment' => 'new_env'));
    

    A safer practice would be to create an app sanboxed in your bundle's tests. You can use JMSCommandBundle to generate it for you. You could also create the sanboxed application looking at bundles using this trick: https://github.com/schmittjoh/JMSPaymentCoreBundle/tree/master/Tests/Functional