可悲的是,使用默认的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()));
这将正常工作,但您正在测试比您应该测试的更多(主要是首先使用匹配器调用它,这是一个实现细节)。
此外,如果您对每个函数有多个调用,这将失败!
接受这两个参数并使用 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()