symfonyphpunitknppaginator

Why PHPUnitTest WebTestCase takes into account previous test?


I have a Symfony 3.2 project with a backend. Each entity has its CRUD Controllers, Views etc. I have prepared an abstract class AbstractControllerTest extends WebTestCase that is a base for tests for each entity. For each entity I use a simple test that asserts that list, show, edit and new returns HTTP 200.

So when I run all test it test list, show etc for each Entity. The problem is that in list Controller I use KNPPaginator with default order. The Controller works OK but when I run tests and it gets to the second entity I get 500 error because of a missing entity field. It turns out that the test takes a list Query for Pager from previous test. So Entity A is ordered by default with a position field. Entity B doesn't have position field and that cause the error. So when PHPUnit goes to test A Entity it is OK, then it moves to test B Entity and then there is an error. I don't know what is going on because ordering is not saved in session so there is no way that PHPUnit gets query from session from previous Entity. Any ideas what is going on?

AbstractControllerTest

abstract class AbstractControllerTest extends WebTestCase
{
    /** @var Client $client */
    public $client = null;

    protected $user = '';
    protected $prefix = '';
    protected $section = '';
    protected $entityId = '';

    public function setUp()
    {
        $this->client = $this->createAuthorizedClient();
    }

    /**
     * @return Client
     */
    protected function createAuthorizedClient()
    {
        $client = static::createClient();
        $client->setServerParameter('HTTP_HOST', $client->getContainer()->getParameter('test_info_domain'));
        $client->setServerParameter('HTTPS', true);
        $client->followRedirects();
        $container = $client->getContainer();

        $session = $container->get('session');
        /** @var $userManager \FOS\UserBundle\Doctrine\UserManager */
        $userManager = $container->get('fos_user.user_manager');
        /** @var $loginManager \FOS\UserBundle\Security\LoginManager */
        $loginManager = $container->get('fos_user.security.login_manager');
        $firewallName = $this->section;

        /** @var UserInterface $userObject */
        $userObject = $userManager->findUserBy(array('username' => $this->user));
        $loginManager->logInUser($firewallName, $userObject);

        // save the login token into the session and put it in a cookie
        $container->get('session')->set('_security_' . $firewallName,
            serialize($container->get('security.token_storage')->getToken()));
        $container->get('session')->save();
        $client->getCookieJar()->set(new Cookie($session->getName(), $session->getId()));

        return $client;
    }

    public function testIndex()
    {
        //CRUD index
        $this->client->request('GET', sprintf('/%s/%s',$this->section,$this->prefix));
        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
    }

    public function testShow()
    {
        //CRUD show
        $this->client->request('GET', sprintf('/%s/%s/%s/show',$this->section,$this->prefix, $this->entityId));
        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
    }

    public function testEdit()
    {
        //CRUD edit
        $this->client->request('GET', sprintf('/%s/%s/%s/edit',$this->section,$this->prefix, $this->entityId));
        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
    }

    public function testNew()
    {
        //CRUD new
        $this->client->request('GET', sprintf('/%s/%s/new',$this->section,$this->prefix));
        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
    }
}

And an example of one of the test class for Controller for one Entity

class AgendaCategoryControllerTest extends AbstractControllerTest
{
    protected $user = 'tom@test.com';
    protected $section = 'admin';
    protected $prefix = 'agenda-category';
    protected $entityId = '40';
}

If I run separately

php phpunit.phar src/Bundle/Tests/Controller/Admin/AControllerTest.php 

and

php phpunit.phar src/Bundle/Tests/Controller/Admin/BControllerTest.php 

it is OK. If run together there is this weird bug

php phpunit.phar -c phpunit.xml.dist --testsuite=Admin

Solution

  • You can reset your test client between tests by doing the following in your setUp-method:

    public function setUp()
    {
        $this->client = $this->createAuthorizedClient();
    
        $this->client->restart();
    }
    

    You might have to move the restart into your createAuthorizedClient-method to ensure it does not reset your auth info.