FMa*_*008 8 php phpunit pdo mocking prepared-statement
我正在尝试使用PHPUnit对mapper类进行单元测试.我可以轻松地模拟将在mapper类中注入的PDO实例,但我无法弄清楚如何模拟PreparedStatement类,因为它是由PDO类生成的.
在我的情况下,我已经扩展了PDO类,所以我有这个:
public function __construct($dsn, $user, $pass, $driverOptions)
{
//...
parent::__construct($dsn, $user, $pass, $driverOptions);
$this->setAttribute(PDO::ATTR_STATEMENT_CLASS,
array('Core_Db_Driver_PDOStatement', array($this)));
}
Run Code Online (Sandbox Code Playgroud)
关键是Core_Db_Driver_PDOStatement没有注入PDO类的构造函数中,它是静态实例化的.即使我这样做:
public function __construct($dsn, $user, $pass, $driverOptions, $stmtClass = 'Core_Db_Driver_PDOStatement')
{
//...
parent::__construct($dsn, $user, $pass, $driverOptions);
$this->setAttribute(PDO::ATTR_STATEMENT_CLASS,
array($stmtClass, array($this)));
}
Run Code Online (Sandbox Code Playgroud)
...它仍然是一个静态的实例,因为我无法传递我自己的预处理语句类的模拟实例.
任何的想法 ?
编辑:解决方案,改编自anwser:
/**
* @codeCoverageIgnore
*/
private function getDbStub($result)
{
$STMTstub = $this->getMock('PDOStatement');
$STMTstub->expects($this->any())
->method('fetchAll')
->will($this->returnValue($result));
$PDOstub = $this->getMock('mockPDO');
$PDOstub->expects($this->any())
->method('prepare')
->will($this->returnValue($STMTstub));
return $PDOstub;
}
public function testGetFooById()
{
$arrResult = array( ... );
$PDOstub = $this->getDbStub($arrResult);
}
Run Code Online (Sandbox Code Playgroud)
edo*_*ian 10
如果你可以模拟PDO类,只需模拟pdo类及其所有依赖项.因为您通过模拟定义输入和输出,所以不需要关心pdo类的语句类或构造函数.
所以你需要一个返回模拟对象的模拟对象.
它可能看起来有点令人困惑但是因为你应该只测试被测试的类所做的事情,而你没有其他任何东西可以解决你的数据库连接的所有其他部分.
在这个例子中,你想弄清楚的是:
如果是这样:一切都好.
<?php
class myClass {
public function __construct(ThePDOObject $pdo) {
$this->db = $pdo;
}
public function doStuff() {
$x = $this->db->prepare("...");
return $x->fetchAll();
}
}
class myClassTest extends PHPUnit_Framework_TestCase {
public function testDoStuff() {
$fetchAllMock = $this
->getMockBuilder("stdClass" /* or whatever has a fetchAll */)
->setMethods(array("fetchAll"))
->getMock();
$fetchAllMock
->expects($this->once())->method("fetchAll")
->will($this->returnValue("hello!"));
$mock = $this
->getMockBuilder("ThePDOObject")
->disableOriginalConstructor()
->setMethods(array("prepare"))
->getMock();
$mock
->expects($this->once())
->method("prepare")
->with("...")
->will($this->returnValue($fetchAllMock));
$x = new myClass($mock);
$this->assertSame("hello!", $x->doStuff());
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5019 次 |
| 最近记录: |