Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking PDO with phpunit

I am trying to mock PDO object to use when writing some tests with phpunit, but I find it pretty complicated and can't find too much documentation about it. I created this xml structure:

<dataset>
    <table name="providers">
            <column>id</column>
            <column>name</column>
            <column>description</column>
            <row>
                    <value>1</value>
                    <value>provdier_1</value>
                    <value>phpunit first provider</value>
            </row>
    </table>
</dataset>

and now I want to query providers table and get the data back but I just cant figure out how to do that.

I started with mocking the PDO object but I don't understand how should I work with it and how to use it inside the getConnection() method. my first attempt, which I'm guessing its quite far from the correct way because I am very lost here, looks something like this:

class AdProvidersTest extends PHPUnit_Extensions_Database_TestCase
{
    public function getConnection()
    {
      $dsn = 'mydb';
      $user = '';
      $password = '';

      $pdo = $this->getMockBuilder('PDOMock')
        ->getMock();

        return $this->createDefaultDBConnection($pdo, 'adserverTesting');
    }

    public function getDataSet()
    {
        return $this->createXMLDataSet('adserverTesting.xml');
    }

}

how can I make the connection interact with the 'adserverTesting.xml' file and how can I query it using this lines:

$ds = new PHPUnit_Extensions_Database_DataSet_QueryDataSet($this->getConnection());
$ds->addTable('adserverTesting', 'SELECT * FROM providers');
like image 351
Donoven Rally Avatar asked Aug 09 '15 10:08

Donoven Rally


2 Answers

You don't have to mock PDO. Here example how it works:

ConnectionTest.php:

<?php

class ConnectionTest extends PHPUnit_Extensions_Database_TestCase
{
    public function getConnection()
    {
        $database = 'myguestbook';
        $user = 'root';
        $password = '';
        $pdo = new PDO('mysql:host=localhost;dbname=myguestbook', $user, $password);
        $pdo->exec('CREATE TABLE IF NOT EXISTS guestbook (id int, content text, user text, created text)');
        return $this->createDefaultDBConnection($pdo, $database);
    }

    public function getDataSet()
    {
        return $this->createFlatXMLDataSet(__DIR__.'/dataSets/myFlatXmlFixture.xml');
    }

    public function testGetRowCount()
    {
        $this->assertEquals(2, $this->getConnection()->getRowCount('guestbook'));
    }
}

myFlatXmlFixture.xml

<?xml version="1.0" ?>
<dataset>
    <guestbook id="1" content="Hello buddy!" user="joe" created="2010-04-24 17:15:23" />
    <guestbook id="2" content="I like it!" user="nancy" created="2010-04-26 12:14:20" />
</dataset>

Result:

PHPUnit 4.7.6 by Sebastian Bergmann and contributors.

.

Time: 215 ms, Memory: 5.25Mb

OK (1 test, 1 assertion)

Main point in tests against db is don't mock db but also create absolutely same PDO connection not to production db but to db for test, it can be mysql, sqlite etc...

like image 192
cn007b Avatar answered Nov 11 '22 21:11

cn007b


Have you tried viewing the documentation? They seem to be using a traditional PDO object using an in-memory sqlite connection by loading it with xml data like you are trying to do

<?php

class AdProvidersTest extends PHPUnit_Extensions_Database_TestCase
{
    /**
     * @return PHPUnit_Extensions_Database_DB_IDatabaseConnection
     */
    public function getConnection()
    {
        $pdo = new PDO('sqlite::memory:');
        return $this->createDefaultDBConnection($pdo, ':memory:');
    }
}

Edit: May 2020 - Unit tests are to test units of code, not to test your data sets. It is best practice to Mock your dependencies to return known data sets, not to query in-memory databases. Querying data is best suited for integration tests, which are an entirely different set of tests. See https://phpunit.readthedocs.io/en/9.1/test-doubles.html?highlight=database#stubs

like image 3
Josh J Avatar answered Nov 11 '22 21:11

Josh J