Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHPUnit: Mocking a method that takes in a parameter

I'm creating tests for a class that takes in a "Search" class, which searches a supermarket using a search string and has a method "getItem($itemNo)" that returns the corresponding item.

So, a bit like this:

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

I want to mock this Search class, as I don't want to search the supermarket everytime I do a test.

So I've written:

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 */]));
    }
}

As you can see in the code, I would like the mock method to take in an integer, like shown in MyClass, which will then return the corresponding pseudoSupermarketItem string. So far I'm not sure how to make this happen, any help is appreciated!

like image 394
r.bilgil Avatar asked Sep 13 '13 14:09

r.bilgil


People also ask

Which method is used to create a mock with PHPUnit?

PHPUnit provides methods that are used to automatically create objects that will replace the original object in our test. createMock($type) and getMockBuilder($type) methods are used to create mock object. The createMock method immediately returns a mock object of the specified type.

What is a stub vs mock?

Stub: a dummy piece of code that lets the test run, but you don't care what happens to it. Substitutes for real working code. Mock: a dummy piece of code that you verify is called correctly as part of the test. Substitutes for real working code.

What is laravel mockery?

When testing Laravel applications, you may wish to "mock" certain aspects of your application so they are not actually executed during a given test. For example, when testing a controller that dispatches an event, you may wish to mock the event listeners so they are not actually executed during the test.


1 Answers

This should work for you:

$this->searchResult
    ->expects($this->any())
    ->method('getItem')
    ->with($this->isType('integer'))
    ->will($this->returnCallback(function($argument) use ($pseudoSupermarketItem) {
        return $pseudoSupermarketItem[$argument];
    });

In additional maybe you may find it useful (using onConsecutiveCalls):

http://phpunit.de/manual/3.7/en/test-doubles.html#test-doubles.stubs.examples.StubTest7.php

The thrid way is something like that:

$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]);
// (...)
like image 196
Cyprian Avatar answered Oct 11 '22 13:10

Cyprian