用 phpunit 模拟 PDO
Mocking PDO with 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
table 并取回数据,但我不知道该怎么做。
我从模拟 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');
您是否尝试查看 documentation?
他们似乎正在使用传统的 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:');
}
}
编辑:2020 年 5 月 - 单元测试用于测试代码单元,而不是测试您的数据集。最好的做法是将您的依赖项模拟为 return 已知数据集,而不是查询内存数据库。查询数据最适合集成测试,这是一组完全不同的测试。参见 https://phpunit.readthedocs.io/en/9.1/test-doubles.html?highlight=database#stubs
根据文档 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/ 之类的迁移工具对于准备数据库和回滚数据库非常有帮助。
你也可以为你 requests/data 一代使用一些伪造者,比如 https://packagist.org/packages/fzaninotto/faker
您不必模拟 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 等...
我正在尝试模拟 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
table 并取回数据,但我不知道该怎么做。
我从模拟 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');
您是否尝试查看 documentation?
他们似乎正在使用传统的 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:');
}
}
编辑:2020 年 5 月 - 单元测试用于测试代码单元,而不是测试您的数据集。最好的做法是将您的依赖项模拟为 return 已知数据集,而不是查询内存数据库。查询数据最适合集成测试,这是一组完全不同的测试。参见 https://phpunit.readthedocs.io/en/9.1/test-doubles.html?highlight=database#stubs
根据文档 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/ 之类的迁移工具对于准备数据库和回滚数据库非常有帮助。 你也可以为你 requests/data 一代使用一些伪造者,比如 https://packagist.org/packages/fzaninotto/faker
您不必模拟 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 等...