2010-11-21 99 views
8

我正在使用PHPUnit進行單元測試我正在使用模擬對象來測試是否使用正確的參數調用方法。這個工作正常,當我只想做一次。如何測試是否用PHPUnit和模擬對象調用了正確的參數相同的方法

$logMock = $this->getMockBuilder('Logger') 
      ->disableOriginalConstructor() 
      ->getMock(); 

    //check if it updates the correct record 
    $logMock->expects($this->exactly(1)) 
      ->method('updateLog') 
      ->with(456, 'some status'); 

現在我有這種情況,我想測試updateLog是否被第二次調用(使用不同的參數)。我看不出用'with'方法如何做到這一點。

有人有建議嗎?

回答

13

我不知道你的嘲笑框架。通常你只是創造另一個期望。我認爲應該與這個框架一起工作。

$logMock->expects($this->exactly(1)) 
     ->method('updateLog') 
     ->with(100, 'something else'); 

編輯

看來,PHPUnit框架不支持在同一個方法多種不同的預期。根據這site你必須使用索引功能。

然後,它將像這樣

$logMock->expects($this->at(0)) 
     ->method('updateLog') 
     ->with(456, 'some status'); 
$logMock->expects($this->at(1)) 
     ->method('updateLog') 
     ->with(100, 'something else'); 
$logMock->expects($this->exactly(2)) 
     ->method('updateLog'); 
+0

我正在使用PHPUnit內部模擬功能。在我的實現(正在測試的方法)中,updateLog被調用兩次,所以我不能測試具有不同期望的方法參數。 – Fino 2010-11-21 16:21:11

+0

根據這個網站,你可以通過使用call-index功能來實現這一點。 http://www.kreamer.org/phpunit-cookbook/1.0/mocks/set-mock-expectations-for-multiple-calls-to-a-function – treze 2010-11-21 20:05:54

+0

謝謝! $ this-> at(index)完成這項工作。也感謝網站的鏈接,一些有用的信息。 – Fino 2010-11-21 20:46:21

1

以前的答案是正確的。

您可以在PHPUnit手冊中找到答案 http://www.phpunit.de/manual/3.6/en/phpunit-book.html#test-doubles.mock-objects.tables.matchers 搜索匹配器。 匹配器是)永遠不會被任何函數(返回的班,()等... 。你需要的是PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex,在由()方法返回

你可以找到通過瀏覽PHPUnit的班多(加到項目路徑並使用像NetBeans一樣的IDE跳轉到它們並查看可以使用的內容)

1

從PHPUnit 4.2開始,您可以使用withConsecutive斷言。只要你知道電話的順序。你假裝是這樣的:

$logMock->expects($this->exactly(2)) 
     ->method('updateLog') 
     ->withConsecutive(
      array(456, 'some status') 
      array(100, 'something else') 
     ); 
0

returnCallback

如果您不能使用withConsecutive(),可能是因爲你是在一箇舊版本的PHPUnit的,你有returnCallback另一種選擇。

每次調用模擬方法時,都會調用returnCallback函數。這意味着您可以保存傳遞給它的參數供以後檢查。例如:

$actualArgs = array(); 

$mockDependency->expects($this->any()) 
    ->method('setOption') 
    ->will($this->returnCallback(
     function($option, $value) use (&$actualArgs){ 
      $actualArgs[] = array($option, $value); 
     } 
    )); 

$serviceUnderTest->executeMethodUnderTest(); 

$this->assertEquals(
    array(
     array('first arg of first call', 'second arg of first call'), 
     array('first arg of second call', 'second arg of second call'), 
    ), 
    $actualArgs); 
相關問題