我正在尝试使用
PHPUnit对mapper类进行单元测试.
我可以轻松地模拟将在mapper类中注入的PDO实例,但我无法弄清楚如何模拟PreparedStatement类,因为它是由PDO类生成的.
我可以轻松地模拟将在mapper类中注入的PDO实例,但我无法弄清楚如何模拟PreparedStatement类,因为它是由PDO类生成的.
在我的情况下,我已经扩展了PDO类,所以我有这个:
public function __construct($dsn,$user,$pass,$driverOptions) { //... parent::__construct($dsn,$driverOptions); $this->setAttribute(PDO::ATTR_STATEMENT_CLASS,array('Core_Db_Driver_PDOStatement',array($this))); }
关键是Core_Db_Driver_PDOStatement没有注入PDO类的构造函数中,它是静态实例化的.即使我这样做:
public function __construct($dsn,$driverOptions,$stmtClass = 'Core_Db_Driver_PDOStatement') { //... parent::__construct($dsn,array($stmtClass,array($this))); }
…它仍然是一个静态的实例,因为我无法传递我自己的预处理语句类的模拟实例.
任何的想法 ?
编辑:
解决方案,改编自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); }
如果你可以模拟PDO类,只需模拟pdo类及其所有依赖项.因为您通过模拟定义输入和输出,所以不需要关心pdo类的语句类或构造函数.
原文链接:https://www.f2er.com/php/137142.html所以你需要一个返回模拟对象的模拟对象.
它可能看起来有点令人困惑,但是因为你应该只测试被测试的类所做的事情,而你没有别的东西可以解决你的数据库连接的所有其他部分.
在这个例子中,你想弄清楚的是:
>准备叫吗?
> fetchAll调用什么准备返回?
>该调用的结果是否返回?
如果是这样:一切都好.
<?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()); } }