web-dev-qa-db-ja.com

PHPUnitでは、モックされたメソッドへの連続した呼び出しで異なるwith()をどのように示すのですか?

期待される異なる引数を使用して、モックされたメソッドを2回呼び出したい。 expects($this->once())は2回目の呼び出しで失敗するため、これは機能しません。

$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番目の呼び出しと一致するようにwith()を追加するにはどうすればよいですか?

44
james

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()に渡されるインデックスは、同じモックオブジェクトへのすべてのメソッド呼び出しに適用されることに注意してください。 2番目のメソッド呼び出しがbar()であった場合、引数をat()に変更しません。

63
David Harkness

同様の質問からの回答 を参照し、

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()を使用することは理想的ではありません

At()マッチャーの$ indexパラメーターは、特定のモックオブジェクトのすべてのメソッド呼び出しで、ゼロから始まるインデックスを参照します。このマッチャーを使用する場合は、特定の実装の詳細と密接に関連している脆弱なテストにつながる可能性があるため、注意が必要です。

23
Gunith D