I'm trying to setup unit tests for my Silex application but I keep getting this error message:
RuntimeException: Either set KERNEL_DIR in your phpunit.xml according to http://symfony.com/doc/current/book/testing.html#your-first-functional-test or override the WebTestCase::createKernel() method.
This is my ./app/phpunit.xml.dist
:
<?xml version="1.0" encoding="UTF-8"?>
<!-- http://www.phpunit.de/manual/current/en/appendixes.configuration.html -->
<phpunit
backupGlobals="false"
backupStaticAttributes="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
bootstrap="phpunit_bootstrap.php"
>
<testsuites>
<testsuite name="Project Test Suite">
<directory>../src/Acme/*/Tests</directory>
</testsuite>
</testsuites>
<!--<php>-->
<!--<server name="KERNEL_DIR" value="/var/www/acme/api/app/" />-->
<!--</php>-->
</phpunit>
This is my ./app/phpunit_bootstrap.php
(that include composer's autoloader):
<?php
if (!@include __DIR__ . '/../../vendor/autoload.php') {
die(<<<'EOT'
You must set up the project dependencies, run the following commands:
wget http://getcomposer.org/composer.phar
php composer.phar install
EOT
);
}
My directory structure is the following:
It looks like phpunit
is looking for *Kernel.php
but I don't know why.
Here is my unit test:
<?php
namespace Acme\User\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class UserControllerTest extends WebTestCase
{
protected $headers;
protected function setUp()
{
$this->headers = array(
'CONTENT_TYPE' => 'application/json',
);
}
public function testAuthUser()
{
$client = static::createClient();
$client->request('POST', ...);
// Check the response content type
$this->assertTrue(
$client->getResponse()->headers->contains(
'Content-Type',
'application/json'
)
);
// Assert that the response status code is 2xx
$this->assertTrue($client->getResponse()->isSuccessful());
$response = json_decode($client->getResponse()->getContent(), true);
var_dump($response);die;
}
}
Ok,
I've managed to make it work. I had several configuration issues.
The first one in my app/phpunit_boostrap.php
, I've added:
<?php
$_SERVER['env'] = 'test';
...
Then in my web/index.php
I've added:
// Return the kernel instead to run it if we are unit testing
if ('test' == $app['mode']) {
return $app;
}
$app->run();
Then in my app/application.php
, I've added:
...
// Set dev mode for unit testing
if (isset($_SERVER['env']) && 'test' === $_SERVER['env']) {
$app['mode'] = 'test';
}
...
I've noticed that I was not using the correct WebTestCase
, Silex
has its own where you need to create the application (set the kernel):
<?php
namespace Acme\User\Tests\Controller;
// Notice the Silex class for the WebTestCase
use Silex\WebTestCase;
class UserControllerTest extends WebTestCase
{
protected $headers;
public function createApplication()
{
// index.php should return the $app instead to run() it
return require __DIR__ . '/../../../../../web/index.php';
}
protected function setUp()
{
// Don't forget to call the parent setup that is setting the kernel
parent::setUp();
$this->headers = array(
'CONTENT_TYPE' => 'application/json',
);
}
public function testAuthUser()
{
// Create a client this way
$client = $this->createClient();
$client->request('POST', ...);
Everything is working nicely now. Also I've create my own WebTestCase
class extending the one from Silex
so that I don't have to setup the application all the time.
I hope this will help some of you as I didn't find any good help about unit testing with Silex.
Cheers, Maxime
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With