Mocking PDO с phpunit

Я пытаюсь обмануть объект PDO, который будет использоваться при написании некоторых тестов с phpunit, но я нахожу его довольно сложным и не могу найти слишком много документации об этом. Я создал эту структуру xml:

<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>

и теперь я хочу запросить таблицу providers и вернуть данные, но я просто не могу понять, как это сделать.

Я начал с насмешки над объектом PDO, но я не понимаю, как мне работать с ним и как его использовать внутри метода getConnection(). моя первая попытка, которую я угадываю, ее довольно далеко от правильного пути, потому что я здесь очень потерян, выглядит примерно так:

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');
    }

}

как я могу заставить соединение взаимодействовать с файлом 'adserverTesting.xml' и как я могу запросить его, используя следующие строки:

$ds = new PHPUnit_Extensions_Database_DataSet_QueryDataSet($this->getConnection());
$ds->addTable('adserverTesting', 'SELECT * FROM providers');

Ответы

Ответ 1

Вам не нужно издеваться над PDO. Вот пример, как это работает:

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>

Результат:

PHPUnit 4.7.6 by Sebastian Bergmann and contributors.

.

Time: 215 ms, Memory: 5.25Mb

OK (1 test, 1 assertion)

Главное в тестах против db - это не издеваться над db, но также создавать абсолютно такое же соединение PDO, а не с производным db, но для db для теста, это могут быть mysql, sqlite и т.д.

Ответ 2

Пробовали ли вы просматривать документацию? Кажется, что они используют традиционный объект PDO, используя соединение sqlite в памяти, загружая его данными xml, как вы пытаетесь сделать

<?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:');
    }
}

Ответ 3

Согласно документации createXMLDataSet xml формат файла

 It is a very simple xml format where a tag inside the root node <dataset> represents exactly one row in the database. The tags name equals the table to insert the row into and an attribute represents the column.

И этот xml файл представляет данные (а не схему).

Я считаю, что вы хотите проверить свои запросы и результаты. Поэтому ИМХО будет лучше использовать тестовую БД и реальное соединение. Инструменты миграции, такие как http://www.liquibase.org/, могут быть очень полезны для подготовки БД и их отката. Также вы можете использовать некоторые подделки для ваших запросов/генерации данных, например https://packagist.org/packages/fzaninotto/faker