我怎么可以进行MockObjects返回的不同价值观基础上的参数?
-
07-07-2019 - |
题
我已经有了一个进行模拟对象,返回 'return value'
不管是什么它的论点:
// From inside a test...
$mock = $this->getMock('myObject', 'methodToMock');
$mock->expects($this->any))
->method('methodToMock')
->will($this->returnValue('return value'));
我希望能够做的是返回的一个不同的价值基础上的参数过于模拟方法。我已经试过这样的:
$mock = $this->getMock('myObject', 'methodToMock');
// methodToMock('one')
$mock->expects($this->any))
->method('methodToMock')
->with($this->equalTo('one'))
->will($this->returnValue('method called with argument "one"'));
// methodToMock('two')
$mock->expects($this->any))
->method('methodToMock')
->with($this->equalTo('two'))
->will($this->returnValue('method called with argument "two"'));
但这引起进行的抱怨如果嘲笑不是所谓的有争论 'two'
, 所以我假定的定义 methodToMock('two')
复盖的定义的第一个。
所以我的问题是:是否有任何方式获得进行模拟对象,以回归不同的价值基于其论点?如果是这样,怎么样?
解决方案
使用回调。例如(直接来自PHPUnit文档):
<?php
class StubTest extends PHPUnit_Framework_TestCase
{
public function testReturnCallbackStub()
{
$stub = $this->getMock(
'SomeClass', array('doSomething')
);
$stub->expects($this->any())
->method('doSomething')
->will($this->returnCallback('callback'));
// $stub->doSomething() returns callback(...)
}
}
function callback() {
$args = func_get_args();
// ...
}
?>
在callback()中执行您想要的任何处理,并根据您的$ args返回结果。
其他提示
来自最新的phpUnit文档:“有时,存根方法应根据预定义的参数列表返回不同的值。您可以使用 returnValueMap()创建一个将参数与相应的返回值相关联的映射。“
$mock->expects($this->any())
->method('getConfigValue')
->will(
$this->returnValueMap(
array(
array('firstparam', 'secondparam', 'retval'),
array('modes', 'foo', array('Array', 'of', 'modes'))
)
)
);
我有一个类似的问题(虽然略有不同......我不需要基于参数的不同返回值,但必须测试以确保将2组参数传递给同一个函数)。我偶然发现了这样的事情:
$mock = $this->getMock();
$mock->expects($this->at(0))
->method('foo')
->with(...)
->will($this->returnValue(...));
$mock->expects($this->at(1))
->method('foo')
->with(...)
->will($this->returnValue(...));
它并不完美,因为它要求知道对foo()的2次调用的顺序,但实际上这可能不是太坏。
您可能希望以OOP方式进行回调:
<?php
class StubTest extends PHPUnit_Framework_TestCase
{
public function testReturnAction()
{
$object = $this->getMock('class_name', array('method_to_mock'));
$object->expects($this->any())
->method('method_to_mock')
->will($this->returnCallback(array($this, 'returnCallback'));
$object->returnAction('param1');
// assert what param1 should return here
$object->returnAction('param2');
// assert what param2 should return here
}
public function returnCallback()
{
$args = func_get_args();
// process $args[0] here and return the data you want to mock
return 'The parameter was ' . $args[0];
}
}
?>
这不是你要求的,但在某些情况下它可以提供帮助:
$mock->expects( $this->any() ) )
->method( 'methodToMock' )
->will( $this->onConsecutiveCalls( 'one', 'two' ) );
onConsecutiveCalls - 以指定的顺序返回值列表
通过两个平阵列,其中每个元件阵列:
- 第一个是方法参数,并且至少是返回的价值。
例如:
->willReturnMap([
['firstArg', 'secondArg', 'returnValue']
])
您也可以按如下方式返回参数:
$stub = $this->getMock(
'SomeClass', array('doSomething')
);
$stub->expects($this->any())
->method('doSomething')
->will($this->returnArgument(0));
正如您在模拟文档中所看到的,该方法 returnValue($ index)
允许返回给定的参数。
你的意思是这样吗?
public function TestSomeCondition($condition){
$mockObj = $this->getMockObject();
$mockObj->setReturnValue('yourMethod',$condition);
}
我遇到了类似的问题,我也无法解决这个问题(关于PHPUnit的信息很少)。就我而言,我只是将每个测试单独测试 - 已知输入和已知输出。我意识到我不需要制作一个万能的模拟对象,我只需要一个特定的测试对象,因此我将测试分开并可以将我的代码的各个方面作为一个单独的测试单元。我不确定这是否适用于您,但这取决于您需要测试的内容。
$this->BusinessMock = $this->createMock('AppBundle\Entity\Business');
public function testBusiness()
{
/*
onConcecutiveCalls : Whether you want that the Stub returns differents values when it will be called .
*/
$this->BusinessMock ->method('getEmployees')
->will($this->onConsecutiveCalls(
$this->returnArgument(0),
$this->returnValue('employee')
)
);
// first call
$this->assertInstanceOf( //$this->returnArgument(0),
'argument',
$this->BusinessMock->getEmployees()
);
// second call
$this->assertEquals('employee',$this->BusinessMock->getEmployees())
//$this->returnValue('employee'),
}
尝试:
->with($this->equalTo('one'),$this->equalTo('two))->will($this->returnValue('return value'));