К сожалению, это невозможно при использовании стандартного PHPUnit Mock API.
Я вижу два варианта, которые могут приблизить вас к чему-то вроде этого:
Использование -> at ($ x)
$context = $this->getMockBuilder('Context')
->getMock();
$context->expects($this->at(0))
->method('offsetGet')
->with('Matcher')
->will($this->returnValue(new Matcher()));
$context->expects($this->at(1))
->method('offsetGet')
->with('Logger')
->will($this->returnValue(new Logger()));
Это будет работать нормально, но вы тестируете больше, чем должны (в основном, сначала вызывается с помощью matcher, а это - деталь реализации).
Также это не удастся, если у вас есть более одного вызова для каждой из функций!
Принятие обоих параметров и использование returnCallBack
Это больше работы, но работает лучше, так как вы не зависите от порядка вызовов:
Рабочий пример:
<?php
class FooTest extends PHPUnit_Framework_TestCase {
public function testX() {
$context = $this->getMockBuilder('Context')
->getMock();
$context->expects($this->exactly(2))
->method('offsetGet')
->with($this->logicalOr(
$this->equalTo('Matcher'),
$this->equalTo('Logger')
))
->will($this->returnCallback(
function($param) {
var_dump(func_get_args());
// The first arg will be Matcher or Logger
// so something like "return new $param" should work here
}
));
$context->offsetGet("Matcher");
$context->offsetGet("Logger");
}
}
class Context {
public function offsetGet() { echo "org"; }
}
Будет выведено:
/*
$ phpunit footest.php
PHPUnit 3.5.11 by Sebastian Bergmann.
array(1) {
[0]=>
string(7) "Matcher"
}
array(1) {
[0]=>
string(6) "Logger"
}
.
Time: 0 seconds, Memory: 3.00Mb
OK (1 test, 1 assertion)
Я использовал $this->exactly(2)
в сопоставителе, чтобы показать, что это также работает с подсчетом вызовов. Если вам не нужно это менять на $this->any()
, конечно, сработает.