PHPUnit Mock稍后改变期望
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PHPUnit Mock稍后改变期望相关的知识,希望对你有一定的参考价值。
我有一个简单的用例。我想有一个setUp方法,它将导致我的模拟对象返回一个默认值:
$this->myservice
->expects($this->any())
->method('checkUniqueness')
->will($this->returnValue(true));
但是在某些测试中,我想返回一个不同的值:
$this->myservice
->expects($this->exactly(1))
->method('checkUniqueness')
->will($this->returnValue(false));
我过去曾使用过GoogleMock for C ++,它有“returnByDefault”或其他东西来处理它。我无法弄清楚这是否可能在phpUnit中(没有api文档,代码很难通读以找到我想要的东西)。
现在我不能只将$this->myservice
更改为新的模拟,因为在设置中,我将其传递给需要模拟或测试的其他事物。
我唯一的另一个解决方案是我失去了设置的好处,而是必须为每次测试建立我的所有模拟。
您可以将setUp()
代码移动到另一个具有参数的方法中。然后从setUp()
调用此方法,您也可以从测试方法调用它,但参数与默认参数不同。
继续在setUp()
中构建模拟,但在每个测试中单独设置期望:
class FooTest extends PHPUnit_Framework_TestCase {
private $myservice;
private $foo;
public function setUp(){
$this->myService = $this->getMockBuilder('myservice')->getMock();
$this->foo = new Foo($this->myService);
}
public function testUniqueThing(){
$this->myservice
->expects($this->any())
->method('checkUniqueness')
->will($this->returnValue(true));
$this->assertEqual('baz', $this->foo->calculateTheThing());
}
public function testNonUniqueThing(){
$this->myservice
->expects($this->any())
->method('checkUniqueness')
->will($this->returnValue(false));
$this->assertEqual('bar', $this->foo->calculateTheThing());
}
}
这两个期望不会相互干扰,因为PHPUnit实例化了一个新的FooTest实例来运行每个测试。
另一个小技巧是通过引用传递变量。这样你可以操纵值:
public function callApi(string $endpoint):bool
{
// some logic ...
}
public function getCurlInfo():array
{
// returns curl info about the last request
}
上面的代码有两个公共方法:callApi()
调用API,第二个getCurlInfo()
方法提供有关最后一个请求的信息。我们可以通过传递一个变量作为参考,根据为getCurlInfo()
提供/模拟的参数来模拟callApi()
的输出:
$mockedHttpCode = 0;
$this->mockedApi
->method('callApi')
->will(
// pass variable by reference:
$this->returnCallback(function () use (&$mockedHttpCode) {
$args = func_get_args();
$maps = [
['endpoint/x', true, 200],
['endpoint/y', false, 404],
['endpoint/z', false, 403],
];
foreach ($maps as $map) {
if ($args == array_slice($map, 0, count($args))) {
// change variable:
$mockedHttpCode = $map[count($args) + 1];
return $map[count($args)];
}
}
return [];
})
);
$this->mockedApi
->method('getCurlInfo')
// pass variable by reference:
->willReturn(['http_code' => &$mockedHttpCode]);
如果仔细观察,returnCallback()
逻辑实际上与returnValueMap()
完全相同,只是在我们的例子中我们可以添加第三个参数:来自服务器的预期响应代码。
以上是关于PHPUnit Mock稍后改变期望的主要内容,如果未能解决你的问题,请参考以下文章