3
我有一個簡單的PHP類,它包裝對數據庫的訪問以檢索用戶並希望對其進行單元測試。目前,我有以下代碼:綁定到實現詳細信息的數據庫單元測試
要測試的類:
class UserTable {
protected $tableGateway;
public function __construct(\Zend\Db\TableGateway\TableGateway $tableGateway) {
$this->tableGateway = $tableGateway;
}
public function getUserWithId($id) {
return $this->tableGateway->select(['id' => $id])->current();
}
}
單元測試:
class UserTableTest extends \PHPUnit_Framework_TestCase {
public function testGetUserWithIdReturnsCorrectUser() {
$user = new User();
$resultSet = new ResultSet();
$resultSet->initialize([$user]);
$mockTableGateway = $this->getMock('\Zend\Db\TableGateway\TableGateway', ['select'], [], '', false);
$mockTableGateway->expects($this->once())->method('select')->with(['id' => 1])->willReturn($resultSet);
$userTable = new UserTable($mockTableGateway);
$this->assertEquals($user, $userTable->getUserWithId(1));
}
}
不過,現在的單元測試想如果我以後決定改變方式失敗我使用表格網關(例如使用select(['id = ?' => $id]
)。這將單元測試綁定到應該避免的getUserWithId($id)
的實現細節。
防止單元測試取決於實現細節的最佳做法是什麼?是否值得努力建立一個單元測試可以運行的實際測試數據庫(這也將大大減緩測試的執行速度)還是有更好的方法來模擬表格網關?
你可以創建自己的網關對象代碼的經驗,你總是使用,然後這些表測試只與一個網關接口,但是應該改變你只改變你的定製網關,而不是使用那個zend表網關的任何地方 – STLMikey 2014-10-28 17:30:26
這就是我的UsersTable實際上設計的目的。要進一步封裝Zend TableGateway併爲應用程序的其餘部分提供一個接口。那麼,你建議增加另一個抽象層次,它簡單地包裝了TableGateway,不包含邏輯,不需要測試? – 2014-12-01 07:41:10