Imaginons un test unitaire sous Symfony qui ne fait rien à part tenter de récupérer l’EntityManager :
namespace Controller;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
class FooControllerTest extends KernelTestCase
{
public function testFoo()
{
$em = $this->getService('doctrine');
$rand = rand(0,1);
$this->assertEquals(1, $rand);
}
protected function getService($id)
{
return self::$kernel
->getContainer()
->get($id);
}
public static function setUpBeforeClass()
{
self::bootKernel();
}
}
Avec un peu de chance l’assertion va fonctionner (1 fois sur 2 en fait). Mais là n’est pas le problème. Ajoutons maintenant un 2ème test :
namespace Controller;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
class FooControllerTest extends KernelTestCase
{
public function testBoo()
{
$em = $this->getService('doctrine');
$rand = rand(0,1);
$this->assertEquals(1, $rand);
}
//--
}
Et on relance le test :
$ ./bin/phpunit tests/Controller/FooControllerTest.php
Et là une erreur apparait, indépendante du test en lui même. Le container a la valeur null
:
1) Controller\FooControllerTest::testBoo
Error: Call to a member function get() on null
Par contre, le premier test passe sans encombre, le service est bien récupéré. Pourquoi ? Il suffit de jeter un œil dans la classe KernelTestCase
:
/**
* Clean up Kernel usage in this test.
*/
protected function tearDown()
{
static::ensureKernelShutdown();
}
Eh oui, Symfony reset lui même le kernel entre chaque test. La solution : surcharger cette méthode dans notre test :
namespace Controller;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
class FooControllerTest extends KernelTestCase
{
// --
protected function tearDown() { }
}
Références externes
- Testing in Symfony (en)
Commentaires récents