使用phpunit模拟PDO

16

我想在使用phpunit编写一些测试时,模拟PDO对象的使用,但我发现这相当复杂,而且找不到太多相关文档。

我创建了这个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');
3个回答

7
您无需模拟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)

在与数据库进行测试时,主要的点是不要模拟数据库,而是创建完全相同的PDO连接,而不是连接到生产数据库,而是连接到用于测试的数据库,它可以是MySQL、SQLite等。


3

你是否尝试查看文档? 他们似乎正在使用传统的PDO对象,通过加载xml数据并使用内存sqlite连接来完成,就像你所尝试的那样。

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

编辑:2020年5月 - 单元测试是为了测试代码单元,而不是为了测试数据集。最佳实践是模拟您的依赖项以返回已知的数据集,而不是在内存数据库中查询。查询数据最适合于集成测试,这是一组完全不同的测试。请参见https://phpunit.readthedocs.io/en/9.1/test-doubles.html?highlight=database#stubs

文档已经过时,新的文档中没有关于此事项的文档。 - user11995521
@PM7Temp 在单元测试中使用数据库通常不是一个好主意。推荐的解决方案是模拟数据方法,在代码中返回已知的数据集。请参见有关示例8.10周围数据库的亮点 https://phpunit.readthedocs.io/en/9.1/test-doubles.html?highlight=database#stubs - Josh J

0
根据文档,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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接