2011-04-29 20 views
39

我想用不同的預期參數兩次調用我的模擬方法。這不起作用,因爲expects($this->once())將在第二次調用時失敗。在PHPUnit中,如何在連續調用模擬方法時指示與()不同?

$mock->expects($this->once()) 
    ->method('foo') 
    ->with('someValue'); 

$mock->expects($this->once()) 
    ->method('foo') 
    ->with('anotherValue'); 

$mock->foo('someValue'); 
$mock->foo('anotherValue'); 

我也試過:

$mock->expects($this->exactly(2)) 
    ->method('foo') 
    ->with('someValue'); 

但我怎麼添加有()第二個呼叫匹配嗎?

+2

爲什麼你需要匹配參數?你不能使用onConsecutiveCalls()來說「第一次,返回這個,第二次返回」?你會正好使用(2)和onConsecutiveCalls() – fiunchinho 2011-04-29 22:34:20

+2

相同的[問題](http://stackoverflow.com/questions/5484602/mock-in-phpunit-multiple-configuration-of-the-same-method-with - 不同的argume)從相關的塊。 – meze 2011-04-29 22:44:10

+2

[phpunit mock method multiple calls with different arguments]可能重複(https://stackoverflow.com/questions/5988616/phpunit-mock-method-multiple-calls-with-different-arguments) – 2017-08-18 05:51:33

回答

51

您需要使用at()

$mock->expects($this->at(0)) 
    ->method('foo') 
    ->with('someValue'); 

$mock->expects($this->at(1)) 
    ->method('foo') 
    ->with('anotherValue'); 

$mock->foo('someValue'); 
$mock->foo('anotherValue'); 

注意,傳遞給at()指標應用在所有的方法調用到相同的模擬對象。如果第二個方法調用爲bar(),則不會將參數更改爲at()

7

the answer from a similar question引用,

由於PHPUnit的4.1,你可以使用withConsecutive如。

$mock->expects($this->exactly(2)) 
    ->method('set') 
    ->withConsecutive(
     [$this->equalTo('foo'), $this->greaterThan(0)], 
     [$this->equalTo('bar'), $this->greaterThan(0)] 
     ); 

如果你想讓它返回的連續通話:

$mock->method('set') 
     ->withConsecutive([$argA1, $argA2], [$argB1], [$argC1, $argC2]) 
     ->willReturnOnConsecutiveCalls($retValueA, $retValueB, $retValueC); 

這不是理想的使用at()如果你能避免它,因爲as their docs claim

爲的$索引參數at()matcher在給定的模擬對象的所有方法調用中引用從零開始的索引。在使用這個匹配器時要小心謹慎,因爲它會導致與特定實現細節密切相關的脆弱測試。

+0

是的,這真的很愚蠢解決方案在phpunit中。每個人都被這個事實所誤導,例如https://addshore.com/2015/08/misled-by-phpunit-at-method/ – forsberg 2018-01-13 17:36:06

相關問題