Solução alternativa para “1701 Não é possível truncar uma tabela referenciada em uma restrição de chave estrangeira” usando doctrine: fixtures: load –purge-with-truncate

Tenho seguido uma abordagem BDD usando Behat para desenvolver uma API RESTful em meu projeto atual e queria isolar totalmente a base de dados de recurso a recurso, então primeiro tentei com:

/**
* @BeforeFeature

*/

public static function beforeFeature(BeforeFeatureScope $scope)
{
echo shell_exec
('app/console doctrine:schema:drop --env=test --force');
echo shell_exec
('app/console doctrine:schema:create --env=test');
echo shell_exec
('app/console doctrine:fixtures:load --env=test -n');
}

e estava bem lento, no meu caso demorava em média 1,5s

Lendo a ajuda do DoctrineFixturesBundle eu encontrei um bom --purge-with-truncatesinalizador, mas TA DAN, estava falhando com este problema: https://github.com/doctrine/data-fixtures/pull/127

Bem, eu resolvi substituindo o método como:MySqlPlatform::getTruncateTableSQL

config_test.yml

doctrine: dbal: driver_class: YourOwnBundleDBALDriver ...

src / Your / OwnBundle / DBAL / Driver.php

<? php

namespace YourOwnBundleDBAL;

use DoctrineDBALDriverPDOMySqlDriver as BaseDriver;

class Driver extends BaseDriver
{
/**
* {@inheritdoc}

*/

public function getDatabasePlatform()
{
return new Platform();
}
}

src / Your / OwnBundle / DBAL / Platform.php

<? php

namespace YourOwnBundleDBAL;

use DoctrineDBALPlatformsMySqlPlatform;

class Platform extends MySqlPlatform
{
/**
* {@inheritdoc}

*/

public function getTruncateTableSQL($tableName, $cascade = false)
{
return sprintf('SET foreign_key_checks = 0;TRUNCATE %s;SET foreign_key_checks = 1;', $tableName);
}
}

E finalmente:

/**
* @BeforeFeature

*/

public static function beforeFeature(BeforeFeatureScope $scope)
{
echo shell_exec
('app/console doctrine:fixtures:load --env=test --purge-with-truncate -n');
}

É hacky, eu sei, mas funciona para os testes e reduz o tempo médio para 0,4s .