2

I'm developing a project with Symfony and Doctrine and I have an issue with my tests. I'm using Fixtures to load data for the tests, and some of my entities have associations between them. The first time I run my tests with empty DB tables the tests succeed flawlessly. But when I run the test once again, I got an error:

Doctrine\DBAL\DBALException: An exception occurred while executing 'DELETE FROM Ent':

SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (my_db.Ent, CONSTRAINT FK_FE5D1D1E727ACA70 FOREIGN KEY (parent_id) REFERENCES Ent (id))

The reason for the error is obvious: a row cannot be deleted when another row is referencing it though a foreign key.

If I manually truncate the table disabling foreign key constrains first and run the test again with an empty table, the tests are successful once again. But I have to repeat this every time I run the tests.

So the question is: is there a way to make Symfony or PHPUnit handle this automatically?

Thanks!

EDIT: I forgot to mention I'm using the Liip\FunctionalTestBundle\Test\WebTestCase class.

A.L
  • 10,259
  • 10
  • 67
  • 98
Guido Kritz
  • 336
  • 2
  • 8

2 Answers2

3

I ended up extending the WebTestCase as suggested by Nextar. Thanks!

This is the code:

<?php

namespace Acme\MyBundle\Tests\Controller;

use Liip\FunctionalTestBundle\Test\WebTestCase;

class MyWebTestCase extends WebTestCase {

  protected function loadFixtures(array $classNames, $omName = null, $registryName = 'doctrine', $purgeMode = null) {
    $this->getContainer()->get('doctrine')->getManager()->getConnection()->query(sprintf('SET FOREIGN_KEY_CHECKS=0'));
    $result = parent::loadFixtures($classNames, $omName, $registryName, $purgeMode);
    $this->getContainer()->get('doctrine')->getManager()->getConnection()->query(sprintf('SET FOREIGN_KEY_CHECKS=1'));
    return $result;
  }
}
Guido Kritz
  • 336
  • 2
  • 8
1

There is a way doing this, you have to write you own WebTestCase which extends the one provided by Symfony

Symfony\Bundle\FrameworkBundle\Test\WebTestCase

In the loadFixtures Mehod of your own WebTestCase you simply use the command component to:

  • Drop the database
  • Create the schema
  • load the fixtures

Dont forget ! If you execute the commands define the --env as test ! Otherwise you will drop your prod database

Then in every functional test you do the whole database will be rebuild, and all fixtures will be loaded

Nextar
  • 1,088
  • 2
  • 12
  • 26