Andree
Andree

Reputation: 3103

Questions regarding PHPUnit mock feature

Can someone provide me a reference to a good PHPUnit mock guide? The one in the official documentation doesn't seem to be detailed enough. I am trying to study PHPUnit by reading the source code, but I am not familiar with the term matcher, invocation mocker, stub return, etc.

I need to know about the following:

1) How to expect multiple calls to a mock object's method, but each return a different sets of value?

$tableMock->expects($this->exactly(2))
    ->method('find')
    ->will($this->returnValue(2)); // I need the second call to return different value

2) How to expect a call to a mock object's method with multiple parameters?

Upvotes: 5

Views: 1849

Answers (2)

Tim Lytle
Tim Lytle

Reputation: 17624

[Note: All code samples from the sites linked, follow the links for more thorough explanations.]

Return Different Values

The (current) PHPUnit documentation suggests using a callback or onConsecutiveCalls():

$stub->expects($this->any())
      ->method('doSomething')
      ->will($this->returnCallback('str_rot13'));

$stub->expects($this->any())
     ->method('doSomething')
     ->will($this->onConsecutiveCalls(2, 3, 5, 7));

Expect Multiple Parameters

with() may contain multiple parameters:

$observer->expects($this->once())
         ->method('reportError')
         ->with($this->greaterThan(0),
                $this->stringContains('Something'),
                $this->anything());

Test Multiple Calls

Although not ask, on a related topic (and not in the PHPUnit documentation that I can find), you can use at() to set expectations for multiple calls to a method:

$inputFile->expects($this->at(0))
          ->method('read')
          ->will($this->returnValue("3 4"));
$inputFile->expects($this->at(1))
          ->method('read')
          ->will($this->returnValue("4 6"));
$inputFile->expects($this->at(2))
          ->method('read')
          ->will($this->returnValue(NULL));

Upvotes: 12

ircmaxell
ircmaxell

Reputation: 165271

You can always create your own mock classes (you don't need to use the built in Mock object):

class tableMock extends Table {
    public function __construct() {
    }

    public function find($id) {
        return $id;
    }
}

$tableMock = new tableMock();

//Do your testing here...

If you want to fail the test from inside of the Mock, just throw an exception...

Upvotes: 3

Related Questions