Naoki Oshiumi
Naoki Oshiumi

Reputation: 101

fails to set up fixture (PHPunit with dbunit )

Trying to setup fixtures for my Phalcon tests, but it fails. Can you figure out what went wrong with my implementation ?

Usage

Current state

unitTestCase.php

<?php

use Phalcon\Di;
use Phalcon\Mvc\Model\Manager as ModelsManager;
use Phalcon\Test\UnitTestCase as PhalconTestCase;
use PHPUnit\DbUnit\TestCaseTrait;

require_once "CustomHelper.php";

// config of phpunit

abstract class UnitTestCase extends PhalconTestCase
{
use TestCaseTrait;

/**
 * @var bool
 */
private $_loaded = false;

public function setUp()
{
    parent::setUp();

    $di = Di::getDefault();

    $di->set(
        "modelsManager",
        function () {
            return new ModelsManager();
        }
    );
    $di["modelsMetadata"] = function () {
        $metadata = new \Phalcon\Mvc\Model\Metadata\Files(
            [
                "metaDataDir" => joinPaths(__DIR__, "/path/to/metadata/"),
            ]
        );

        return $metadata;
    };
    $di->setShared('mockControllerHelper', new mockControllerHelper());
    $di->setShared('helper', new Helpers());
    $di->setShared('config', function () {
        return require CONFIG_DIR . 'app.php';
    });

    $di->setShared('db', function () {
        $config = $this->getConfig();

        // database configuration from app.php
        $class = 'Phalcon\Db\Adapter\Pdo\\' . $config->database->adapter;
        $params = [
            'host' => $config->database->host,
            'username' => $config->database->username,
            'password' => $config->database->password,
            'dbname' => $config->database->dbname,
        ];

        if ($config->database->adapter == 'Postgresql') {
            unset($params['charset']);
        }

        $connection = new $class($params);

        return $connection;
    });
    $this->setDi($di);

    $this->_loaded = true;
}

public function tearDown()
{
    /* This static call cleans up the Mockery container used by the current test, and run any verification tasks needed for our expectations. */
    \Mockery::close();
}

/**
 * Check if the test case is setup properly
 *
 * @throws \PHPUnit_Framework_IncompleteTestError;
 */
public function __destruct()
{
    if (!$this->_loaded) {
        throw new \PHPUnit_Framework_IncompleteTestError(
            "Please run parent::setUp()."
        );
    }
}



 // Setting part of dbunit
static private $pdo = null;

private $conn = null;

final public function getConnection()
{
    require CONFIG_DIR . 'app.php';
    if ($this->conn === null) {
        if (self::$pdo == null) {
            self::$pdo = new PDO(
                'mysql:host='. $globalConfig->database->host .';dbname=test',
                $globalConfig->database->username,
                $globalConfig->database->password
            );
        }
        $this->conn = $this->createDefaultDBConnection(self::$pdo, 'dbname=test');
    }

     return $this->conn;
}

}

TestControllerTest.php

<?php

namespace Test\Controllers;

use PHPUnit\DbUnit\DataSet\YamlDataSet;

class DatabaseTest extends \UnitTestCase
{
    protected function getDataSet()
    {
        return new YamlDataSet(__DIR__ . "/../DataSet/dataSet.yml");
    }

    public function testsTableRow() {
        $this->assertEquals(1, $this->getConnection()->getRowCount('testRow'), "");
    }
}

DataSet

testRow:
  -
    id: 1
    name: 'test'
    text: 'hello, world'

Response

Failed asserting that 0 matches expected 1.

Note

When I use a real mysql database connection in getConnection, and call $this->getConnection()->getRowCount('testRow'), the result is correct. Therefore, the problem seems to come from loading the yaml dataset

supplementation1

The contents of $this->getConnection is :

(execute print_r($this->getConnection(), false);)

(                                                                                                                                             
    [connection:protected] => PDO Object                                                                                                      
        (                                                                                                                                     
        )                                                                                                                                     

    [metaData:protected] => PHPUnit\DbUnit\Database\Metadata\MySQL Object                                                                     
        (                                                                                                                                     
            [schemaObjectQuoteChar:protected] => `                                                                                            
            [pdo:protected] => PDO Object                                                                                                     
                (                                                                                                                             
                )                                                                                                                             

            [schema:protected] => dbname=test                                                                                         
            [truncateCommand:protected] => TRUNCATE                                                                                           
        )
)

The contents of $this->getDataSet() is :

(execute print_r($this->getDataSet(), false);)

(                                                                                                                                             
    [tables:protected] => Array                                                                                                               
        (                                                                                                                                     
            [testRow] => PHPUnit\DbUnit\DataSet\DefaultTable Object                                                                           
                (                                                                                                                             
                    [tableMetaData:protected] => PHPUnit\DbUnit\DataSet\DefaultTableMetadata Object                                           
                        (                                                                                                                     
                            [columns:protected] => Array                                                                                      
                                (                                                                                                             
                                    [0] => id                                                                                                 
                                    [1] => name                                                                                               
                                    [2] => text                                                                                               
                                )                                                                                                             

                            [primaryKeys:protected] => Array                                                                                  
                                (                                                                                                             
                                )                                                                                                             

                            [tableName:protected] => testRow                                                                                  
                        )                                                                                                                     

                    [data:protected] => Array                                                                                                 
                        (                                                                                                                     
                            [0] => Array                                                                                                      
                                (                                                                                                             
                                    [id] => 1                                                                                                 
                                    [name] => test
                                    [text] => hello, world
                                )

                        )

                    [other:PHPUnit\DbUnit\DataSet\AbstractTable:private] =>
                )

        )

    [parser:protected] => PHPUnit\DbUnit\DataSet\SymfonyYamlParser Object
        (
        )

)

Upvotes: 1

Views: 575

Answers (1)

xmike
xmike

Reputation: 1038

Dbunit has to perform some setup operations and they are defined in PHPUnit\DbUnit\TestCaseTrait in setUp() method (you can see more code details here. When you inherit PHPUnit\DbUnit\TestCase you mostly do not have to worry about it (other than just making sure to call parent::setUp() from your testcase). When using functionality directly from the trait you have to make sure that dbunit's set up is also invoked. You can achieve this by smth like below:

<?php
use Phalcon\Test\UnitTestCase as PhalconTestCase;
use PHPUnit\DbUnit\TestCaseTrait;

abstract class UnitTestCase extends PhalconTestCase
{
    use TestCaseTrait {
        setUp as protected dbunitSetUp;
    };

    public function setUp()
    {
        parent::setUp(); // phalcon setup
        $this->dbuintSetUp(); // dbunit setup
    }
}

For the sample above only the lines relevant to the problem are included, skipping other stuff like getConnection, etc.

Upvotes: 1

Related Questions