I'm currently learning how to test database's in the PHPUnit framework, and ran across the problem that I don't want to connect to a real database in my tests. This because when I run the tests on another computer, this computer might not have the same database.
I implemented the \PHPUnit\DbUnit\TestCaseTrait trait and set up the following methods:
/**
* Returns the test database connection.
*
* @return \PHPUnit\DbUnit\Database\Connection
*/
protected function getConnection()
{
$pdo = new PDO('sqlite::memory:');
return $this->createDefaultDBConnection($pdo, ':memory:');
}
/**
* Returns the test dataset.
*
* @return \PHPUnit\DbUnit\DataSet\IDataSet
*/
protected function getDataSet()
{
return $this->createXMLDataSet(dirname(__FILE__) . '/test-dataset.xml');
}
The dataset file is present, and is found properly.
In my setUp method from my test, I set a variable in the object to a \PDO instance.
/**
* @var PDO $databaseServerConnection
*/
private $databaseServerConnection;
public function setUp()
{
$this->databaseServerConnection = $this->getConnection()->getConnection();
}
I expected I could now use that PDO connection with the data that came from the dataset file in the getDataSet() method.
For my own try, I tried comparing those with the following code:
# Specify the tables we want to have in our connection dataset
$tables = ['users'];
# Create the dataset in the connection with the tables
$dataset = $this->getConnection()->createDataSet($tables);
# Query all results from the user table in the connection
$queryTable = $this->getConnection()->createQueryTable(
'users', 'SELECT * FROM users'
);
# Get the raw table data from the dataset file
$expectedTable = $this->getDataSet()->getTable('users');
# Check if theyre equal
$this->assertTablesEqual($queryTable, $expectedTable);
When debugging this, I noticed that the $tables array variable inside the $dataset is just a empty. Here a var_dump of the $dataset variable.
class PHPUnit\DbUnit\Database\FilteredDataSet#18 (3) {
protected $tableNames =>
array(1) {
[0] =>
string(5) "users"
}
protected $tables =>
array(0) {
}
protected $databaseConnection =>
class PHPUnit\DbUnit\Database\DefaultConnection#16 (2) {
protected $connection =>
class PDO#15 (0) {
}
protected $metaData =>
class PHPUnit\DbUnit\Database\Metadata\Sqlite#17 (6) {
protected $columns =>
array(0) {
...
}
protected $keys =>
array(0) {
...
}
protected $truncateCommand =>
string(11) "DELETE FROM"
protected $pdo =>
class PDO#15 (0) {
...
}
protected $schema =>
string(8) ":memory:"
protected $schemaObjectQuoteChar =>
string(1) """
}
}
}
Also the $data array inside the $queryTable variable is null. Here a var_dump of he $queryTable variable.
class PHPUnit\DbUnit\DataSet\QueryTable#22 (6) {
protected $query =>
string(19) "SELECT * FROM users"
protected $databaseConnection =>
class PHPUnit\DbUnit\Database\DefaultConnection#20 (2) {
protected $connection =>
class PDO#19 (0) {
}
protected $metaData =>
class PHPUnit\DbUnit\Database\Metadata\Sqlite#21 (6) {
protected $columns =>
array(0) {
...
}
protected $keys =>
array(0) {
...
}
protected $truncateCommand =>
string(11) "DELETE FROM"
protected $pdo =>
class PDO#19 (0) {
...
}
protected $schema =>
string(8) ":memory:"
protected $schemaObjectQuoteChar =>
string(1) """
}
}
protected $tableName =>
string(5) "users"
protected $tableMetaData =>
NULL
protected $data =>
NULL
private $other =>
NULL
}
This while the $data array inside the $expectedTable variable is full of the data created in the dataset file.
class PHPUnit\DbUnit\DataSet\DefaultTable#30 (3) {
protected $tableMetaData =>
class PHPUnit\DbUnit\DataSet\DefaultTableMetadata#34 (3) {
protected $columns =>
array(3) {
[0] =>
string(2) "id"
[1] =>
string(4) "name"
[2] =>
string(5) "email"
}
protected $primaryKeys =>
array(0) {
}
protected $tableName =>
string(5) "users"
}
protected $data =>
array(4) {
[0] =>
array(3) {
'id' =>
string(1) "1"
'name' =>
string(3) "test1"
'email' =>
string(9) "[email protected]"
}
[1] =>
array(3) {
'id' =>
string(1) "2"
'name' =>
string(3) "test2"
'email' =>
string(9) "[email protected]"
}
[2] =>
array(3) {
'id' =>
string(1) "3"
'name' =>
string(6) "test3"
'email' =>
string(12) "[email protected]"
}
[3] =>
array(3) {
'id' =>
string(1) "4"
'name' =>
string(4) "test4"
'email' =>
string(10) "[email protected]"
}
}
private $other =>
NULL
}
I also tried to execute 2 queries on the pdo connection object inside the getConnection() method to create the table with values inside them:
protected function getConnection()
{
$pdo = new PDO('sqlite::memory:');
$pdo->exec("CREATE TABLE users (id PRIMARY KEY, name VARCHAR(50), email VARCHAR(50))");
$pdo->exec("INSERT INTO users (id, name, email) VALUES (20, 'Bas', 'aa@me')");
return $this->createDefaultDBConnection($pdo, ':memory:');
}
How does it come that my there isn't any of the data available in my connection and how can I import the data from the dataset file into here to make the test pass?
Also, is this a good practice for doing this?