我正在为一个带有“搜索”类的类创建测试,该类使用搜索字符串搜索超市并且具有返回相应项的方法“getItem($ itemNo)”。
所以,有点像这样:
class MyClass
{
public function __construct(Search $search) {
$item0 = $search->getItem(0);
$item1 = $search->getItem(1);
// etc... you get the picture
}
}
我想模仿这个Search类,因为我不想在每次测试时搜索超市。
所以我写了:
class MyClassTest extends PHPUnit_Framework_TestCase
{
public function setUp()
{
$searchResults=$this->getMockBuilder('Search')
//Because the constructor takes in a search string:
->disableOriginalConstructor()
->getMock();
$pseudoSupermarketItem=array( "SearchResult1", "SearchResult2", etc...);
$this->searchResult
->expects($this->any())
->method('getItem')
->with(/*WHAT DO I PUT HERE SO THAT THE METHOD WILL TAKE IN A NUMBER*/)
->will($this->returnValue($pseudoSupermarketItem[/* THE NUMBER THAT WAS PUT IN */]));
}
}
正如您在代码中看到的,我希望mock方法接受一个整数,如MyClass中所示,然后返回相应的pseudoSupermarketItem字符串。到目前为止,我不确定如何实现这一点,任何帮助都表示赞赏!
答案 0 :(得分:4)
这应该适合你:
$this->searchResult
->expects($this->any())
->method('getItem')
->with($this->isType('integer'))
->will($this->returnCallback(function($argument) use ($pseudoSupermarketItem) {
return $pseudoSupermarketItem[$argument];
});
另外,您可能会发现它很有用(使用onConsecutiveCalls
):
http://phpunit.de/manual/3.7/en/test-doubles.html#test-doubles.stubs.examples.StubTest7.php
第三种方式就是这样:
$this->searchResult
->expects($this->at(0))
->method('getItem')
->with($this->equalTo(0))
->will($this->returnValue($pseudoSupermarketItem[0]);
$this->searchResult
->expects($this->at(1))
->method('getItem')
->with($this->equalTo(1))
->will($this->returnValue($pseudoSupermarketItem[1]);
// (...)
答案 1 :(得分:2)
PHPUnit为输入参数应触发定义的返回值的情况提供returnValueMap()
。
// Create a map of arguments to return values.
$map = array(
array(0, 'SearchResult0'),
array(1, 'SearchResult1')
);
// Configure the stub.
$searchResults->expects($this->any())
->method('getItem')
->will($this->returnValueMap($map));
$this->assertEquals('SearchResult0', $searchResults->getItem(0));
$this->assertEquals('SearchResult1', $searchResults->getItem(1));
$this->assertEquals('SearchResult0', $searchResults->getItem(0));
地图确实看起来有点奇怪,因为没有直接的key->值赋值,但这是因为这个地图也适用于模拟方法的多个输入参数。
$mockedAddition = array(
array(0, 0, 0),
array(0, 1, 1),
array(1, 0, 1),
array(1, 1, 2),
);
$calculator->expects($this->any())
->method('add')
->will($this->returnValueMap($mockedAddition);
$this->assertSame(0, $calculator->add(0, 0)); // Returns the value x of (0, 0, x)
$this->assertSame(1, $calculator->add(1, 0)); // Returns the value x of (1, 0, x)
$this->assertSame(1, $calculator->add(0, 1)); // Returns the value x of (0, 1, x)