免責聲明:是的,我已經閱讀了FAQ,並在Stackoverflow的邊界內考慮了這樣一個問題。不,我不知道如何正確命名它。 :(如何進行單元測試並重構此PHP函數?
我的問題很簡單:如何單元測試下面的方法和我應該做的重構,使之可測試我再說一遍:我不想要求DB和Yii應用實例左右浮動測試這個功能。
public function getOrderCountGroupedByStatus()
{
$arr = $this->db->createCommand()
->select('COUNT(status) AS count_status, status')
->from('order_item')
->group('status')
->order('status')
->queryAll();
$orderItemsCountByStatus = array();
foreach($arr as $os)
$orderItemsCountByStatus[(int)$os['status']] = $os['count_status'];
return $orderItemsCountByStatus;
}
這是遺留代碼通過手動測試整個應用程序進行有效性檢查。
它是基於Yii framework PHP應用程序。
$this->db
是一個CDbConnection對象。 $this->db->createCommand()
返回一個CDbCommand對象。
CDbCommand.queryAll()
返回在每次迭代時發出數組array('status' => (string), 'count_status' => (int))
的可迭代對象。
這種方法顯然有兩個責任:第一個從外部數據源獲取原始數據,第二個將原始數據重新排列到最終結果。我知道它應該以某種方式分開。
- 數據庫接口使用工廠方法,該方法返回帶有可鏈式方法的對象。這是嘲弄的噩夢。我開始爲CDbCommand和創建CDbConnection的CDbConnection編寫手動僞造代碼,但是我已經編寫了很多代碼,可能需要它自己的單元測試。我完全不理解我應該如何嘲笑對數據庫的請求。
- 這段代碼只是一個例子。我有很多類似的方法,但他們中的很多人不是一次調用數據庫,而是多次調用數據庫,所以「獲取原始數據,重新格式化」可能不是這裏的模式,但我不確定。
最後:我正在測試在這裏受相關PHPUnit的測試方法的名稱描述:
public function CanFindNumberOfOrdersGroupedByStatus()
爲什麼我在這裏停留
主要的原因是什麼,我測試基本上是是否SUT能成功從持久性存儲獲得一些統計數據,就這些了。與數據庫的所有交互都是實現細節,但在我使用的遺留代碼中,它是連接持久性存儲的唯一方式(使用上面的CDbCommand/CDbConnection組合),而這個持久性存儲是MySQL數據庫。
我想知道我是否需要實現CDbConnection的完整後端,它將使用內存中的燈具而不是真正的數據庫來正確地對這些方法進行單元測試。
是的,防止可能的問題,項目政策禁止在Yii框架中內置的ActiveRecords的使用。
設置一個單獨的測試數據庫,並簡單地測試已知結果? –
@IvoRenkema男人,我在這裏談論'單位'測試。整個問題是**而不是**使用真正的數據庫,否則每個人都知道如何測試這樣的功能。 – hijarian