2012-04-12 50 views
3

我必須爲php類編寫測試,該類使用由我們使用的apache擴展創建的資源類型,但讓我們假設它是一個帶有mysql資源類型的數據庫類。模擬php的單元測試資源類型

顯然我想嘲笑這些全局函數,但是當類檢查資源是否創建好時如何僞造返回類型?

php文檔中的資源頁面甚至有一條評論抱怨測試無法進行模擬。這是最終的答案嗎?

比方說,我有(例如瘸)代碼:

class DB { 
    function init(){ 
    $this->handle = mysql_connect('myserver'); 
    if(get_resource_type($this->handle) != 'mysql') return false; 
     return true; 
    } 
} 

,然後測試對於成功和失敗的考驗,通過嘲諷mysql_connect

回答

4

也許你有點遙遠。實際上,使用PHP進行測試的資源是非常好的,你可以得到他們的類型等等。pp ..

不容易測試的是它們所代表的依賴關係。您通常不會注入這些資源,但您可以在這些資源上編碼。我們稱之爲對象反轉導向。

中心是對象(資源)和屬於它的程序樣式中的代碼始終具有該資源的相關性。讓我們捲曲爲例:

$url = 'http://example.com/'; 
$handle = curl_init($url); 
curl_exec($handle); 

由於各地$handle對象這不是在這個意義上mockable使用模擬更換功能,如果捲曲是一些其他的代碼依賴這個程序的風格。所以,你需要首先把它包起來,使其注射:

$url = 'http://example.com/'; 
$curl = new Curl($url); 
$curl->exec(); 

這都與你需要的資源爲中心的面向對象轉換成一個普通的舊式PHP對象價格:

class Curl 
{ 
    private $handle; 
    public function __construct($url) { 
     $this->handle = curl_init($url); 
    } 
    public function exec() { 
     return curl_exec($this->handle); 
    } 
} 

這很容易現在來嘲笑它。好的是,這通常是可能的,所以通常資源本身不應該對測試施加任何限制,它只是一些缺少的封裝,所以您需要先添加它。

由於全局靜態狀態,某些API(如imap擴展名)不允許創建乾淨的對象接口,如果是IMAP擴展名,則是錯誤處理。但是它仍然越來越接近,如果缺陷被記錄下來,那也是有幫助的。

+0

我沒有看到你指向...如果我要測試這個類,並且在curl_exec之前檢查資源的類型是原始捲曲類型?我不希望它使用真正的捲曲功能? – gcb 2012-04-13 17:27:25

+1

@gcb:你可能要單元測試'Curl'類(當你這樣做時,句柄是一個內部的,不需要測試),或者你想測試一些其他使用Curl的組件'類,那麼你可以給它一個'Curl'類的模擬。 – hakre 2012-04-13 18:02:38

+0

如果我正在測試'Curl'類,那麼如何避免打擊Web服務器和不一致呢? – gcb 2012-04-13 18:06:04