2010-07-21 123 views
17

我試圖配置PHPUnit中一個模擬對象返回不同屬性的值(即正在使用的功能__get訪問)的PHPUnit - 創建模擬對象充當存根屬性

實施例:

class OriginalObject { 
public function __get($name){ 
switch($name) 
case "ParameterA": 
    return "ValueA"; 
case "ParameterB": 
    return "ValueB"; 
} 
} 

我想用這個來嘲笑:

$mockObject = $this->getMock("OrigionalObject"); 

$mockObject ->expects($this->once()) 
    ->method('__get') 
    ->with($this->equalTo('ParameterA')) 
    ->will($this->returnValue("ValueA")); 

$mockObject ->expects($this->once()) 
    ->method('__get') 
    ->with($this->equalTo('ParameterB')) 
    ->will($this->returnValue("ValueB")); 

但這種可怕的失敗:-(

+1

是錯別字(「原始」,而不是「原始」,缺少的值a和valueB收盤行情)在模擬代碼是你的實際代碼的一部分,還是抄寫錯誤? – Phil 2010-07-29 12:59:46

+1

大聲笑感謝菲爾(指出我的閱讀障礙) 錯字(現在修改)只是在示例代碼 - 顯然這不是正在執行的實際代碼 – Tim 2010-07-30 05:56:18

回答

9

我還沒有嘗試過嘲諷__get還,但也許這將工作:

// getMock() is deprecated 
// $mockObject = $this->getMock("OrigionalObject"); 
$mockObject = $this->createMock("OrigionalObject"); 

$mockObject->expects($this->at(0)) 
    ->method('__get') 
    ->with($this->equalTo('ParameterA')) 
    ->will($this->returnValue('ValueA')); 

$mockObject->expects($this->at(1)) 
    ->method('__get') 
    ->with($this->equalTo('ParameterB')) 
    ->will($this->returnValue('ValueB')); 

我已經使用$這個 - >在()在測試和它的作品(但不是最佳解決方案) 。我是從這個胎面:

How can I get PHPUnit MockObjects to return different values based on a parameter?

+0

哎koen $ this-> at()適合我 - 謝謝;-) 爲什麼你不認爲這是一個最佳的解決方案? – Tim 2010-07-30 05:58:15

+1

這不是真正的可擴展性,測試很難閱讀。如果你給它一個好名字,回調可能會更容易閱讀。但首先,我會考慮重構__get。 – koen 2010-07-30 06:41:01

+0

另外,你正在測試狀態(有些人認爲是不好的做法),甚至更多的是私人狀態(許多人認爲這是不好的做法)。當然,有些聰明的人並沒有看到問題,你可能就是其中之一。 – koen 2010-07-30 06:44:50

4

這應該工作:

class Test extends \PHPUnit_Framework_TestCase { 
... 
    function testSomething() { 
     $mockObject = $this->getMock("OrigionalObject"); 

     $mockObject 
       ->expects($this->any()) 
       ->method('__get') 
       ->will($this->returnCallback('myMockGetter')); 
     ... 
    } 
... 
} 

function myMockGetter($classPropertyName) { 
    switch($classPropertyName) { 
     case 'ParameterA': 
      return 'ValueA'; 

     case 'ParameterB': 
      return 'ValueB'; 
    } 
} 
... ... 
+0

我認爲我的解決方案比koen更優化,但他在評論中提出了一些重要的觀點。我認爲一種可能的解決方案是創建一個測試類,而不是使用模擬對象。這通常用於諸如HTTP適配器之類的東西。 – 2011-09-02 01:56:44