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