2012-10-03 93 views
2

我一直在努力讓我們的系統與PHPUnit更加兼容,所以我們可以對類進行更多的單元測試,並設法讓它們中的一些模擬對象工作,但是我已經碰到一個我似乎無法解決的問題。在PHPUnit模擬對象中返回不同的結果

我們有一個類(我創建一個模擬版本)用於查詢。將查詢字符串傳遞給它的「query()」方法,它將記錄查詢,運行查詢並返回結果。它還使用名爲「get_row()」的方法封裝了mysql_fetch_assoc,該方法返回的數組值與原始數據非常相似。

問題是,在某些方法中,有多個查詢被傳遞給「query()」方法,因此需要通過多個while循環運行以將數據加載到不同的變量中。我已經創建了一個簡化版本:

class object{ 
    public function __construct($query){ 
     $this->query = $query; 
    } 

    public function loadData(){ 

     $data1 = queryDataSource("SELECT * FROM data1"); 
     $data2 = queryDataSource("SELECT * FROM data2"); 

     return Array(
      "data1" => $data1, 
      "data2" => $data2, 
     ); 

    } 

    private function queryDataSource($query){ 
     $this->query->query($query) 

     while($row = $this->query->get_row()){ 
      $result[] = $row; 
     } 

     return $result 
    } 
} 

class testObject extends PHPUnit_Framework_TestCase{ 
    method testLoadData(){ 
     $test_data = Array('name' => 'Bob', 'number' => '98210'); 

     $query = $this->getMock('Query'); 
     $query->expects($this->any())->method('query'); 
     $query->expects($this->at(1))->method('get_row')->will($this->returnValue($test_data); 
     $query->expects($this->at(2))->method('get_row')->will($this->returnValue(False); 
     $query->expects($this->at(3))->method('get_row')->will($this->returnValue($test_data); 
     $query->expects($this->at(4))->method('get_row')->will($this->returnValue(False); 
    } 
} 

爲了避免第一次while循環$對象 - > queryDataSource()我返回FALSE布爾值,因爲這樣做mysql_fetch_assoc何時會發生。問題是,當它試圖運行第二個查詢並通過get_row()獲取數據時,模擬對象似乎保持返回FALSE ratehr而不是繼續到at(3)點。即使有4個對象也會發生這種情況,只有第一個會將測試數據作爲返回值,第二次獲取FALSE,其他每次都會得到FALSE。

有誰知道是否有辦法解決這個問題?我嘗試刪除FALSE標誌,只是在at()中有奇數值,但是有同樣的問題,我試着讓它返回(1-2)的數據,但是它只是將所有數據傳入首先while循環,而另一個則什麼也不做。

感謝您的幫助,您可以給,望

回答

7

,因爲它似乎只能是僞代碼,但是從我的理解,我不能運行代碼不夠清晰的問題的是,你試圖嘲弄的說明像這樣:

Call to query, get_row, get_row, query, get_row, get_row. 

問題,你似乎遇到了是->at()匹配數不按method起來,但每object計數。

所以,你可能希望寫的是:

$query->expects($this->any())->method('query'); 
    $query->expects($this->at(1))->method('get_row')->will($this->returnValue($test_data); 
    $query->expects($this->at(2))->method('get_row')->will($this->returnValue(False); 
    $query->expects($this->at(4))->method('get_row')->will($this->returnValue($test_data); 
    $query->expects($this->at(5))->method('get_row')->will($this->returnValue(False); 

或者使其豆蔻easer到甚至閱讀:

$query->expects($this->at(0))->method('query'); 
    $query->expects($this->at(1))->method('get_row')->will($this->returnValue($test_data); 
    $query->expects($this->at(2))->method('get_row')->will($this->returnValue(False); 
    $query->expects($this->at(3))->method('query'); 
    $query->expects($this->at(4))->method('get_row')->will($this->returnValue($test_data); 
    $query->expects($this->at(5))->method('get_row')->will($this->returnValue(False); 

有了您的嘲弄你遇到了問題,第二呼叫「查詢」正在計數一個「呼叫」,因此跳過第二個return($test_data);

+0

對於延遲響應抱歉,轉移到另一個項目,但應該能夠很快回到這個。這看起來可能是問題,會讓你知道它是否工作 – SolidSquid

+0

這樣做的工作,我曾認爲at()的索引是相對於方法而不是對象,所以它跳過了「查詢」過程的一部分。另外,抱歉沒有發佈正在工作的代碼。它基於我正在使用的代碼,但是寫成了一個簡化版本,我沒有機會在發佈之前測試它 – SolidSquid

1

不幸的是,at()非常強烈地將您的測試與實現綁定在一起。

試想一下,如果你重新安排一個測試方法內2個的方法調用,功能是正是相同,但使用at()現在會失敗,往往與神祕的消息,如method doesn't exist at index N

在次所有測試要明確地說,「這就是所謂的正是這種方式」,這很好,但如果你只是想斷言,那麼PHPUnit模擬擴展之一似乎更友好,特別是Mockery和指南here(我相信過時的接觸)

還有其他也是。

+0

edorian的解決方案解決了這個問題,但會看看Mockery,看看它是否可以用過的。在這方面有更多的靈活性會很有用。謝謝(你的)信息 – SolidSquid

相關問題