Search code examples
phpdoctrine-ormsymfonyfunctional-testingfixtures

(Symfony 3 / Doctrine 2 ) update of fixtures saves chagens but doesn't get them in WebTestCase


recently, I have began to with TDD, and I was writing a functional test using Symfony 3, Doctrine 2, fixtures and WebTestCase. Yesterday, I found a strange behaviour in my test:

CONTEXT That is a test for the edit function of a RESTfull API, so that I have to be logged (with JWT) to can edit the profile. That is what I do on my setUp function. The (JWT-)Token is sent to the edit controller together with the changes I want to update. That works like a charm.

PROBLEM The problem comes out when I get the updated values from the database and compare them with those that I have sent. They should be the same, but they are not... The most strange thing is that I'm filtering the query to be compared with the values I'm using to compare. That means if there are any row in the database with this values MUST have the same values I'm comparing.

My LoadUserData.php

namespace BackendBundle\DataFixtures\ORM;

use BackendBundle\Entity\User;
use Doctrine\Common\DataFixtures\FixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;

class LoadUserData implements FixtureInterface
{
    static public $users = array();

    /**
     * {@inheritDoc}
     */
    public function load(ObjectManager $manager)
    {
        $user = new User();
        $user->setUsername('User1');
        $user->setEmail('[email protected]');
        $user->setPassword('user1');
        $user->setDateValidFrom(new \DateTime('2016-10-11 12:22:25'));
        $user->setProfilePicture('test.jpg');
        $user->setDateValidTo(new \DateTime('2016-10-11 12:22:25'));
        $user->setDateLastEdited(new \DateTime('2016-10-11 12:22:25'));
        $user->setUsergroup(null);

        $user2 = new User();
        $user2->setUsername('User2');
        $user2->setEmail('[email protected]');
        $user2->setPassword('user2');
        $user2->setDateValidFrom(new \DateTime('2016-10-11 12:22:25'));
        $user2->setProfilePicture('test.jpg');
        $user2->setDateValidTo(new \DateTime('2016-10-11 12:22:25'));
        $user2->setDateLastEdited(new \DateTime('2016-10-11 12:22:25'));
        $user2->setUsergroup(null);

        $manager->persist($user);
        $manager->persist($user2);

        $manager->flush();


        self::$users = array($user, $user2);

    }
}

My UserControllerTest.php

namespace tests\BackendBundle\Controller;


use BackendBundle\DataFixtures\ORM\LoadUserData;
use BackendBundle\Entity\User;
use Liip\FunctionalTestBundle\Test\WebTestCase;

class UserControllerTest extends WebTestCase
{

    private $jwtService;
    private $jwt;
    private $userRep;
    private $currentUser;

    public function setUp(){
        $this->jwtService = $this->getContainer()->get('app.jwt_auth');
        $this->userRep = $this->getContainer()->get('doctrine')->getManager()
            ->getRepository('BackendBundle:User');


        $fixtures = array('BackendBundle\DataFixtures\ORM\LoadUserData');
        $this->loadFixtures($fixtures);
        $users = LoadUserData::$users;
        /** @var User $user */
        $user = $users[0];
        $this->currentUser = $user;

        ************* THE USER HAVE TO BE LOGGED TO CAN EDIT HIS PROFILE ******************
        $this->jwt = $this->jwtService->signup(
            $user->getEmail(),
            $user->getPassword(),
            true
        );
        $this->client = static::createClient();
    }

    public function testEditAction() {

        $route =  $this->getUrl(
            'edit',
            array(
                'authorization' => $this->jwt,
                'json' => '{"email":"[email protected]","username":"admin","password":"admin"}',
                '_format' => 'json'
            )
        );
        $this->client->request('POST', $route, array('ACCEPT' => 'application/json'));
        $response = $this->client->getResponse();


        **************** GET THE USER WITH THE NEW EMAIL ****************
        /** @var User $updatedUser */
        $updatedUser = $this->userRep->findOneBy( 
            array('email' => '[email protected]')
        );
        ************* COMPARE NEW EMAIL WITH THE SENT ONE ***********
        $this->assertEquals($updatedUser->getEmail(), '[email protected]');
    }
}

The Results of the tests:

1) tests\BackendBundle\Controller\UserControllerTest::testEditAction

Failed asserting that two strings are equal.

--- Expected

+++ Actual @@ @@

-'[email protected]'

+'[email protected]'

Thank you very much!


Solution

  • Try forcing the reload of the data using the refresh method on the entity manager object as follow:

        **************** GET THE USER WITH THE NEW EMAIL ****************
        /** @var User $updatedUser */
        $updatedUser = $this->userRep->findOneBy( 
            array('email' => '[email protected]')
        );
    
        $em = $this->getContainer()->get('doctrine')->getManager();
        $em->refresh($updatedUser);
    
        ************* COMPARE NEW EMAIL WITH THE SENT ONE ***********
        $this->assertEquals($updatedUser->getEmail(), '[email protected]');
    

    Hope this help