Question

I'm writing a test for my entity Post, where I'm using blameable behavior from StofDoctrineExtensionsBundle. But whatever I do, there is always an error:

PDOException: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'created_by' cannot be null

Part of my Post class:

namespace My\BlogBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * Post
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="My\BlogBundle\Entity\PostRepository")
 * @ORM\HasLifecycleCallbacks
 * @ORM\ChangeTrackingPolicy("DEFERRED_EXPLICIT")
 */
class Post
{
    /**
     * @Gedmo\Blameable(on="create")
     * @ORM\ManyToOne(targetEntity="My\UserBundle\Entity\User", inversedBy="posts")
     * @ORM\JoinColumn(name="created_by", referencedColumnName="id", nullable=false)
     */
    private $createdBy;

    /* ... */
}

My 1 version of PostTest class:

namespace My\BlogBundle\Tests\Entity;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;

class PostTest extends WebTestCase
{
    /**
     * @var \Doctrine\ORM\EntityManager
     */
    private $em;

    public function setUp()
    {
        static::$kernel = static::createKernel();
        static::$kernel->boot();
        $this->em = static::$kernel->getContainer()
            ->get('doctrine')
            ->getManager()
        ;
    }

    protected function loginAs($client, $username) {
        $container = $client->getContainer();
        $doctrine = $container->get('doctrine');

        $user = $this->loadUser($doctrine, $username);

        // First Parameter is the actual user object.
        // Change 'main' to whatever your firewall is called in security.yml
        $container->get('security.context')->setToken(
            new UsernamePasswordToken(
                $user, null, 'main', $user->getRoles()
            )
        );
    }

    private function loadUser($doctrine, $username) {
        // Assumes User entity implements UserInterface
        return $doctrine
                ->getRepository('MyUserBundle:User')
                ->findOneByUsername($username);
    }

    public function testAddEntity() {
        $this->loginAs(static::createClient(), 'Tester');

        $newEntity = new \My\BlogBundle\Entity\Post;
        $newEntity->setTitle('Test Add Entity');
        $this->em->persist($newEntity);

        $this->em->flush(); /* here is an error */
    }

    protected function tearDown()
    {
        parent::tearDown();
        $this->em->close();
    }
}

And second:

namespace My\BlogBundle\Tests\Entity;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class PostTest extends WebTestCase
{
    /**
     * @var \Doctrine\ORM\EntityManager
     */
    private $em;

    public function setUp()
    {
        static::$kernel = static::createKernel();
        static::$kernel->boot();
        $this->em = static::$kernel->getContainer()
            ->get('doctrine')
            ->getManager()
        ;
    }

    public function testAddEntity() {
        $client = static::createClient(array(), array(
            'PHP_AUTH_USER' => 'Tester',
            'PHP_AUTH_PW'   => '1234',
        ));

        $newEntity = new \My\BlogBundle\Entity\Post;
        $newEntity->setTitle('Test Add Entity');
        $this->em->persist($newEntity);

        $this->em->flush(); /* here is an error */
    }

    protected function tearDown()
    {
        parent::tearDown();
        $this->em->close();
    }
}

Code is working fine in real controller when I'm logged in, there is Tester user in my test database (in another test I'm testing this this account and it's ok), but I can't convince blameable to use this account in test.

First PostTest class is based on this answer.

No correct solution

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top