我正在使用 PHPUnit 为一个方法编写单元测试。我正在测试的方法对同一对象调用同一方法 3 次,但使用不同的参数集。我的问题与here和here
提出的问题类似其他帖子中提出的问题与仅采用一个参数的模拟方法有关。
但是,我的方法需要多个参数,我需要这样的东西:
$mock->expects($this->exactly(3))
->method('MyMockedMethod')
->with(
$this->logicalOr(
$this->equalTo($arg1, $arg2, arg3....argNb),
$this->equalTo($arg1b, $arg2b, arg3b....argNb),
$this->equalTo($arg1c, $arg2c, arg3c....argNc)
)
);
此代码不起作用,因为
equalTo()
仅验证一个参数。给它多个参数会引发异常:
PHPUnit_Framework_Constraint_IsEqual::__construct() 的参数 #2 必须是数字
有没有一种方法可以对具有多个参数的方法进行
logicalOr
模拟?
就我而言,答案非常简单:
$this->expects($this->at(0))
->method('write')
->with(/* first set of params */);
$this->expects($this->at(1))
->method('write')
->with(/* second set of params */);
关键是使用
$this->at(n)
,其中n
是该方法的第N次调用。我无法对我尝试过的任何 logicalOr()
变体做任何事情。
对于其他希望匹配输入参数并为多个调用提供返回值的人..这对我有用:
$mock->method('myMockedMethod')
->withConsecutive([$argA1, $argA2], [$argB1, $argB2], [$argC1, $argC2])
->willReturnOnConsecutiveCalls($retValue1, $retValue2, $retValue3);
$map = array(
array('arg1_1', 'arg2_1', 'arg3_1', 'return_1'),
array('arg1_2', 'arg2_2', 'arg3_2', 'return_2'),
array('arg1_3', 'arg2_3', 'arg3_3', 'return_3'),
);
$mock->expects($this->exactly(3))
->method('MyMockedMethod')
->will($this->returnValueMap($map));
或者你可以使用
$mock->expects($this->exactly(3))
->method('MyMockedMethod')
->will($this->onConsecutiveCalls('return_1', 'return_2', 'return_3'));
如果您不需要指定输入参数
如果有人在没有查看 phpunit 文档中的对应部分的情况下发现了这一点,您可以使用 withConsecutive 方法
$mock->expects($this->exactly(3))
->method('MyMockedMethod')
->withConsecutive(
[$arg1, $arg2, $arg3....$argNb],
[arg1b, $arg2b, $arg3b....$argNb],
[$arg1c, $arg2c, $arg3c....$argNc]
...
);
唯一的缺点是代码必须按照提供参数的顺序调用 MyMockedMethod。我还没有找到解决这个问题的方法。
由于建议的
withConsecutive()
方法现已弃用,您可以在测试中添加这样的方法:
private function consecutively(Constraint ...$values): Callback
{
return self::callback(
static function($value) use (&$values) {
self::assertThat($value, array_shift($values));
return true;
}
);
}
那么你可以这样使用:
$mock->method('myMockedMethod')
->with($this->consecutively([$argA1, $argA2], [$argB1, $argB2], [$argC1, $argC2]))