8
我試圖用PHPUnit單元測試映射類。 我可以輕鬆地模擬將被注入到mapper類中的PDO實例,但我無法弄清楚如何模擬PreparedStatement類,因爲它是由PDO類生成的。PHPUnit - 如何模擬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)));
}
的一點是,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)));
}
...它仍然是一個靜態的instanciation,因爲我無法通過準備好的語句類的我自己的嘲笑實例。
有什麼想法?
編輯: 解決方案,改編自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);
}
準確地說,你確實發現了我沒有太明白的部分:當你可以僞造fetch時,不需要注入語句,否則返回的東西可以在測試中決定。我編輯了我的問題來放置我的改編解決方案。謝謝 ! – FMaz008 2011-03-18 14:53:29
這種方法的問題是它將應用程序代碼實現暴露給測試。測試應該知道應用程序是否正在調用 - > fetch()或fetchAll()?一點也不!如果代碼適用於使用fetch()而不是fetchaAll(),該方法仍然可以正常工作,但測試將失敗。 – 2013-03-08 17:26:28
@TomB,這是嘲笑依賴性的一個普遍問題,而不僅僅是這個答案。 – PeerBr 2014-06-10 14:59:25