简体   繁体   English

PHPUnit:如何使用多个参数模拟多个方法调用?

[英]PHPUnit: how do I mock multiple method calls with multiple arguments?

I am writing a unit test for a method using PHPUnit.我正在为使用 PHPUnit 的方法编写单元测试。 The method I am testing makes a call to the same method on the same object 3 times but with different sets of arguments.我正在测试的方法在同一个对象上调用同一个方法 3 次,但使用不同的参数集。 My question is similar to the questions asked here and here我的问题类似于这里这里提出的问题

The questions asked in the other posts have to do with mocking methods that only take one argument.其他帖子中提出的问题与只采用一个参数的模拟方法有关。

However, my method takes multiple arguments and I need something like this:但是,我的方法需要多个参数,我需要这样的东西:

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

This code doesn't work because equalTo() validates only one argument.此代码不起作用,因为equalTo()仅验证一个参数。 Giving it more than one argument throws an exception:给它多个参数会引发异常:

Argument #2 of PHPUnit_Framework_Constraint_IsEqual::__construct() must be a numeric PHPUnit_Framework_Constraint_IsEqual::__construct() 的参数 #2 必须是数字

Is there a way to do a logicalOr mocking for a method with more than one argument?有没有办法对具有多个参数的方法进行逻辑或logicalOr

Thanks in advance.提前致谢。

In my case the answer turned out to be quite simple:就我而言,答案很简单:

$this->expects($this->at(0))
    ->method('write')
    ->with(/* first set of params */);

$this->expects($this->at(1))
    ->method('write')
    ->with(/* second set of params */);

The key is to use $this->at(n) , with n being the Nth call of the method.关键是使用$this->at(n) ,其中n是该方法的第 N 个调用。 I couldn't do anything with any of the logicalOr() variants I tried.我无法对我尝试过的任何logicalOr()变体做任何事情。

For others who are looking to both match input parameters and provide return values for multiple calls.. this works for me:对于希望匹配输入参数并为多个调用提供返回值的其他人..这对我有用:

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

Stubbing a method call to return the value from a 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));

Or you can use或者你可以使用

$mock->expects($this->exactly(3))
    ->method('MyMockedMethod')
    ->will($this->onConsecutiveCalls('return_1', 'return_2', 'return_3'));

if you don't need to specify input arguments如果您不需要指定输入参数

In case someone finds this without looking at the correspondent section in the phpunit documentation, you can use the withConsecutive method如果有人在没有查看 phpunit 文档中的相应部分就发现了这一点,您可以使用withConsecutive方法

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

The only downside of this being that the code MUST call the MyMockedMethod in the order of arguments supplied.唯一的缺点是代码必须按照提供的参数顺序调用MyMockedMethod I have not yet found a way around this.我还没有找到解决这个问题的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM