Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set foreign key constraints off in PHPUnit/DBUnit

I am developing Unit tests for testing model functions.

I am using PHP PDO with DBUnit 1.1.2 and PHPUnit 3.6.10 and my dataset is a yml file.

I need to turn off foreign key checks while the fixtures are being loaded in the database. After that I need to turn it on again so that I can run my tests under those constraints.

Below is a snippet (not the entire class file) of code in my generalized Testcase file which I will include for any new test case I develop.

When I run a test case under these settings these settings i found that $pdo->exec() is not executing.

What is wrong with my approach? Is there a better alternative?

class MyTestCase extends PHPUnit_Extensions_Database_TestCase {

public function getConnection() {
  $this->pdo = $this->getPDO();

  echo "BEFORE FOREIGN KEY QUERY\n";
  $conn =  $this->createDefaultDBConnection($this->pdo, 'my-schema');
  $this->pdo->exec("set foreign_key_checks=0");

  return $conn;
}

private function getPDO() {
  include BASEPATH . '/application/config/database.php';
  $dbt = $db['testing'];
  $conn_string = sprintf("%s:host=%s;dbname=%s", $dbt['dbdriver'], $dbt['hostname'],     $dbt['database']);
  $pdo = new PDO($conn_string, $dbt['username'], $dbt['password']);
  return $pdo;
}

public function getDataSet() {
  echo "BEFORE FOREIGN KEY QUERY in getDataSet\n";
  $this->pdo->exec("set foreign_key_checks=1");
  return new PHPUnit_Extensions_Database_DataSet_YamlDataSet(ROOTPATH."/application/tests/data/my-dataset.yml");
}

public function setUp() {
   parent::setUp();
}
like image 626
Abhishek Avatar asked Mar 28 '12 08:03

Abhishek


3 Answers

Change your function setUp like this

protected function setUp() {
   $conn=$this->getConnection();
   $conn->getConnection()->query("set foreign_key_checks=0");
   parent::setUp();
    $conn->getConnection()->query("set foreign_key_checks=1");
}
like image 143
Michel Bobillier Avatar answered Nov 03 '22 00:11

Michel Bobillier


Thanks to the comments from @user2045006 and @marcini, I've created the below solution for my project.

class MyDbTestCase extends PHPUnit_Extensions_Database_TestCase
{
    protected function getConnection()
    {
        // ... as normal ...
    }

    protected function getSetUpOperation()
    {
        // Override
        return new PHPUnit_Extensions_Database_Operation_Composite([
            PHPUnit_Extensions_Database_Operation_Factory::TRUNCATE(),
            new InsertOperationWithoutFkChecks(),
        ]);
    }

}

// Custom subclass
class InsertOperationWithoutFkChecks extends PHPUnit_Extensions_Database_Operation_Insert
{
    public function execute(
        PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection,
        PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet
    ) {
        $connection->getConnection()->exec("SET foreign_key_checks = 0");
        parent::execute($connection, $dataSet);
        $connection->getConnection()->exec("SET foreign_key_checks = 1");
    }
}
like image 4
LinusR Avatar answered Nov 03 '22 00:11

LinusR


Sometimes it can be a case of manually truncating the tables beforehand and ensuring the ordering of your dataset is correct i.e. parent table first and then the reliant child tables. You can then avoid setting foreign_key_checks every test

like image 1
sufcboy Avatar answered Nov 03 '22 00:11

sufcboy