0

I'm trying to execute a simple PHPUnit test using the "@runInSeparateProcess" annotation and a PDO connection, but it raise the following exception :

PHPUnit_Framework_Exception: PHP Fatal error: Uncaught exception 'PDOException' with >>message 'You cannot serialize or unserialize PDO instances' in -:37

I just can't figure what going wrong. Here's my piece of code

<?php
require_once 'PHPUnit/Extensions/Database/TestCase.php';

/**
 * @runTestsInSeparateProcesses
 */
class myTest extends PHPUnit_Extensions_Database_TestCase{

    private $pdo = null;

    public function __construct() {

        $this->pdo = new Pdo('sqlite::memory:');        
        try{
        $this->pdo->exec('CREATE TABLE post (
                id INTEGER NOT NULL,
                title TEXT(100),
                PRIMARY KEY (id),
                UNIQUE (id)
            )'
        );
        } catch(PDOException $e){
            echo $e->getMessage();
        }
    }

    /**
     * @return PHPUnit_Extensions_Database_DB_IDatabaseConnection
     */
    public function getConnection(){  
        return $this->createDefaultDBConnection($this->pdo, 'sqlite');
    }

    /**
     * @return PHPUnit_Extensions_Database_DataSet_IDataSet
     */
    public function getDataSet(){       
        return $this->createFlatXMLDataSet(dirname(__FILE__).'/test.xml');
    }   

    protected function getSetUpOperation(){     
        return PHPUnit_Extensions_Database_Operation_Factory::CLEAN_INSERT();
    }   

    public function testFirst(){
        $this->assertEquals(1,1);
    }

    public function testSecond(){
        $this->assertEquals(1,1);
    }


}
jpta
  • 1
  • 1
  • Check this [question](http://stackoverflow.com/questions/5234432/zf-doctrine2-phpunit-error-pdoexeption-you-cannot-serialize-or-unserialize-p). – Bram Gerritsen Jul 13 '13 at 15:02

1 Answers1

2

PHPUnit will serialize and unserialize your class between tests in order to preserve the value of any variables in the global scope (which is going to include $pdo). This prevents one test from modifying the variables and affecting the next test; each test starts "clean."

I believe your solution would be to move initialization of $pdo out of the constructor and into the getConnection() method. Then the PDO object is not going to be serialized. If you are concerned about the overhead of creating that connection for each test, just check if you have already created it and return an existing resource.

Something like the code below which is a mix of your code and the sample on the PHPUnit site: http://phpunit.de/manual/3.7/en/database.html#database.tip-use-your-own-abstract-database-testcase

// only instantiate pdo once for test clean-up/fixture load
static private $pdo = null;

// only instantiate PHPUnit_Extensions_Database_DB_IDatabaseConnection once per test
private $conn = null;

/**
 * @return PHPUnit_Extensions_Database_DB_DefaultDatabaseConnection
 */
final public function getConnection()
{
    if ($this->conn === null) {
        if (self::$pdo == null) {
            self::$pdo = new PDO('sqlite::memory:');        
            try{
                $this->pdo->exec('CREATE TABLE post (
                    id INTEGER NOT NULL,
                    title TEXT(100),
                    PRIMARY KEY (id),
                    UNIQUE (id)
                )'
            );
            } catch(PDOException $e){
                echo $e->getMessage();
            }
        }
        $this->conn = $this->createDefaultDBConnection($this->pdo, 'sqlite');
    }

    return $this->conn;
}
mcarson
  • 2,602
  • 2
  • 14
  • 15