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

匿名 (未验证) 提交于 2019-12-03 02:44:02

问题:

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

Argument #2 of PHPUnit_Framework_Constraint_IsEqual::__construct() must be a numeric

Is there a way to do a logicalOr mocking for a method with more than one argument?

Thanks in advance.

回答1:

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



回答2:

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



回答3:

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


回答4:

In case someone finds this without looking at the correspondent section in the phpunit documentation, you can use the withConsecutive method

$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. I have not yet found a way around this.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!