2
這裏的類我試圖測試的一個高度簡化的版本:PHPUnit的 - 懲戒數據庫功能
class SimpleORM {
private $table, $pdo;
public function __construct(PDO $pdo, $table) {
$this->pdo = $pdo;
$this->table = $table;
}
public function findById($id) {
$stmt = $this->pdo->prepare('SELECT * FROM ' . $this->table . ' WHERE ' . $this->primaryKey() . ' = :id');
$stmt->execute(array(':id' => $id);
return $stmt->fetch(PDO::FETCH_OBJ);
}
}
所以,我的問題是,我怎麼寫這個類的測試?
我可以嘲笑PDO,像這樣:
public function testFindById() {
$pdo = $this->getMock('PDO', array('prepare'));
$stmt = $this->getMock('PDOStatement', array('execute', 'fetch'));
$stmt->expects($this->once())->method('execute')->with($this->equalTo(array(':id' => 123)));
$stmt->expects($this->once())->method('fetch');
$pdo->expects($this->once())->method('prepare')
->with($this->equalTo('SELECT * FROM test WHERE id => :id'))
->will($this->returnValue($stmt));
$mapper = new SimpleOrm($pdo, 'test');
$mapper->findById(123);
}
這種方法的問題是暴露findById()
方法測試的內部工作,如果他們改變測試甚至會失敗,雖然方法可能已被重構爲正確工作。
爲了使findById()
方法取得成功,就必須調用pdo::prepare()
它必須返回一個具有和fetch()
方法(如PDOStatement對象確實此刻)的對象。但是,如何在不向測試公開方法的實現的情況下對此進行測試?
這當然會導致一個不太脆弱的測試,但這意味着測試PDO以及應用程序代碼,這不是一個真正的單元測試,因爲被測試的代碼不是孤立的。這就是說,這絕對是比嘲笑PDO更好的解決方案。 – 2013-03-11 10:01:28