PHPUnit:模拟接受参数的方法


PHPUnit: Mocking a method that takes in a parameter

我正在为一个接受"搜索"类的类创建测试,该类使用搜索字符串搜索超市,并具有返回相应项的方法"getItem($itemNo)"。

所以,有点像这样:

class MyClass 
{
    public function __construct(Search $search) {
        $item0 = $search->getItem(0);
        $item1 = $search->getItem(1);
        // etc... you get the picture
    }
}

我想模拟这个搜索类,因为我不想每次做测试时都搜索超市。

所以我写了:

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 所示,然后返回相应的伪超市项字符串。到目前为止,我不确定如何实现这一目标,感谢任何帮助!

这应该适合您:

$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]);
// (...)

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

该映射乍一看确实有点奇怪,因为没有直接的键>值赋值,但那是因为此映射也适用于模拟方法的多个输入参数。

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