2010-03-22 25 views
9

我建立單元測試Foo類,我是相當新的單元測試的多個存根。PHPUnit的 - 同一類

我班的一個關鍵組件是BarCollection的一個實例,它包含許多Bar對象。 Foo中的一種方法遍歷集合並在集合中的每個對象上調用幾個方法。我想使用存根對象爲我的測試類生成一系列響應。我如何使Bar存根類在迭代時返回不同的值?我想沿着這些線路做一些事情:

$stubs = array(); 
foreach ($array as $value) { 
    $barStub = $this->getMock('Bar'); 
    $barStub->expects($this->any()) 
      ->method('GetValue') 
      ->will($this->returnValue($value)); 
    $stubs[] = $barStub; 
} 
// populate stubs into `Foo` 

// assert results from `Foo->someMethod()` 

所以Foo->someMethod()會產生基於它從Bar對象接收結果數據。但是,這給了我下面的錯誤,每當數組是長於一個:

There was 1 failure: 

1) testMyTest(FooTest) with data set #2 (array(0.5, 0.5)) 
Expectation failed for method name is equal to <string:GetValue> when invoked zero or more times. 
Mocked method does not exist. 
/usr/share/php/PHPUnit/Framework/MockObject/Mock.php(193) : eval()'d code:25 

我想過是使用->will($this->returnCallback())調用回調方法,但我不知道如何指示回調哪些Bar對象正在進行調用(並因此產生了什麼響應)。

另一個想法是使用onConsecutiveCalls()方法或類似的東西來告訴我的存根第一次返回1,第二次返回2,但我不確定如何做到這一點。我還擔心,如果我的課程除了對集合進行有序迭代之外還有其他任何事情,我將無法對其進行測試。

回答

2

我遺憾的是不知道,如果你能解決使用getMock())本身是超薄您的實際問題,但我與getMock(經驗。

只有我能想到的副手,但不知道你的酒吧類的東西,這可能不是幫助:getMock(),您可以通過構造函數參數(如數組)的第三個參數。

我會創建我自己的模擬類,擴展Bar作爲測試助手(只是另一個類,它恰好只用於測試中的花哨名稱),它完全符合我喜歡的內容,並將它們插入一系列你的Foo對象。這給你所有你想要的控制,因爲你可以直接更換有問題的方法,這getMock()沒有做。不過我建議你寫每類測試一個單獨的測試類,無論如何,但也有情況下,這是不必要的純粹 - 當然,這也意味着你沒有測試酒吧類在這個測試中,這可能不是你想要什麼。

$stubs = array(); 
foreach ($array as $value) { 
    $stubs[] = new MyBarTestHelper($value); 
} 

除此之外,我真的很驚訝,你只有看到當你有多個數組元素時描述的異常。我注意到PHPUnit實際上希望你聲明你希望它能夠跟蹤的任何方法作爲參數,並且會嚴格地錯誤出來,否則,因爲它基本上是在內部做的是創建它自己的擴展類,使用允許它確定是否調用它的邏輯(=將方法名稱添加到邏輯列表中)來包裝每個您明確聲明的方法。

所以顏色我天真(嚴重的是,我大概是,我是一個新手測試,我自己),但看看這可以幫助你的任何:

$stubs = array(); 
foreach ($array as $value) { 
    $barStub = $this->getMock('Bar', array('GetValue')); 
    $barStub->expects($this->any()) 
      ->method('GetValue') 
      ->will($this->returnValue($value)); 
    $stubs[] = $barStub; 
} 
+0

創建我自己的測試課程基本上是我必須做的。在我的例子中,我能夠使用'Bar'類本身,因爲我使用的方法是簡單的getter,但是手工製作的mock類可以使用更復雜的方法。 – keithjgrant 2010-03-30 16:40:16

+0

關於作爲第二個參數傳遞給'getMock()'的有效方法數組:根據文檔,可以省略此參數,並且允許任何方法調用。 – keithjgrant 2010-03-30 16:41:14

+0

這也是我直覺上的理解,但是我確實得到了錯誤,忽略了它,我沒有明確地提到被調用的方法(當然只能與' - > expect()')結合使用;因此提到它。不過,我觀察到的可能是特定版本的bug。但是,無論如何,我很高興您能夠按照您的要求進行測試。 :) – pinkgothic 2010-03-30 20:55:10

0

這應滿足的要求,以便返回一系列值,如果你是舒適的使用全球這就是所謂的。它不知道調用了哪個Bar,但是如果每個Bar都由Foo調用一次,那麼填充測試數據應該不會太困難。

$barTestData = array('empty',1,2,3,4,5,6); 

function barDataCallback(){ 
    global $barTestData; 
    return next($barTestData); 
} 
0

我注意到在代碼中的「 - > method('GetValue')」後面有一個額外的括號。不知道你是否複製並粘貼了該文件。

+0

修正了拼寫錯誤,謝謝。這不是一個直接的複製粘貼。在我的代碼中,我還有其他一些事情正在醞釀中, – keithjgrant 2010-03-26 23:33:08

+0

我無法用您發佈的代碼重新創建您的問題。我想你必須發佈你實際做的才能得到一個好的答案。 – Sean 2010-03-27 22:12:54

+0

有趣。我更多地探討了這一點,而且我沒有收到上面引用的同樣的錯誤消息。我想知道是否是由於我必須解決的另一個錯誤而導致的。現在我的測試似乎運行得很好,但當它們通過時失敗。 – keithjgrant 2010-03-30 16:39:17