PHPUnit:如何模拟具有多个参数的多个方法调用?

busg9geu  于 2023-01-01  发布在  PHP
关注(0)|答案(4)|浏览(139)

我正在使用PHPUnit为一个方法编写单元测试。我正在测试的方法对同一对象的同一方法调用了3次,但使用了不同的参数集。我的问题与herehere的问题类似
其他帖子中提出的问题都与只接受一个参数的模拟方法有关。
然而,我的方法需要多个参数,我需要这样的东西:

$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::__构造()的参数#2必须是数字
有没有办法对一个有多个参数的方法进行logicalOr模拟?

0sgqnhkj

0sgqnhkj1#

就我而言,答案其实很简单:

$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()变体都无法执行任何操作。

7vhp5slm

7vhp5slm2#

对于那些既希望匹配输入参数又希望为多个调用提供返回值的人来说,这对我很有效:

$mock->method('myMockedMethod')
         ->withConsecutive([$argA1, $argA2], [$argB1, $argB2], [$argC1, $argC2])
         ->willReturnOnConsecutiveCalls($retValue1, $retValue2, $retValue3);
pwuypxnk

pwuypxnk3#

存根方法调用以从Map返回值

$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'));

如果不需要指定输入参数

lhcgjxsq

lhcgjxsq4#

如果有人在没有查看phpunit文档中相应部分的情况下发现了这个问题,您可以使用withConsecutive方法

$mock->expects($this->exactly(3))
     ->method('MyMockedMethod')
     ->withConsecutive(
         [$arg1, $arg2, $arg3....$argNb],
         [arg1b, $arg2b, $arg3b....$argNb],
         [$arg1c, $arg2c, $arg3c....$argNc]
         ...
     );

这样做的唯一缺点是代码必须按照提供参数的顺序调用MyMockedMethod。我还没有找到解决这个问题的方法。

相关问题