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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10954107/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 23:26:25  来源:igfitidea点击:

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

phpmockingtddphpunit

提问by Thomas

I am writing a unit test for a method using 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. My question is similar to the questions asked hereand here

我正在为使用 PHPUnit 的方法编写单元测试。我正在测试的方法在同一个对象上调用同一个方法 3 次,但使用不同的参数集。我的问题类似于这里这里提出的问题

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. Giving it more than one argument throws an exception:

此代码不起作用,因为equalTo()仅验证一个参数。给它多个参数会引发异常:

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 logicalOrmocking for a method with more than one argument?

有没有办法对logicalOr具有多个参数的方法进行模拟?

Thanks in advance.

提前致谢。

回答by dr Hannibal Lecter

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 nbeing the Nth call of the method. I couldn't do anything with any of the logicalOr()variants I tried.

关键是使用$this->at(n)n作为方法的第 N 次调用。我无法对logicalOr()我尝试过的任何变体做任何事情。

回答by Cody A. Ray

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

回答by scriptin

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

如果您不需要指定输入参数

回答by Pedro A.

In case someone finds this without looking at the correspondent sectionin the phpunit documentation, you can use the withConsecutivemethod

如果有人在没有查看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 MyMockedMethodin the order of arguments supplied. I have not yet found a way around this.

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