zombor
zombor

Reputation: 3257

PHPUnit multiple mocked methods of the same name

I'm wondering how to go about testing this. Say I have a getter method, and I change the value in the process of a method. Here's a simple example:

public function foo($model)
{
  var_dump($model->state());
  $model->state('saved');
  var_dump($model->state());
}

I mock the model like so:

$model = $this->getMock('Model');
$model->expects($this->any))
  ->method('state')
  ->will($this->returnValue('new'));

How should I setup the mock so that the second call returns a different value (saved)?

Upvotes: 1

Views: 677

Answers (2)

markus
markus

Reputation: 40685

With Mockery, which integrates with PHPUnit but is a far superior mocking library, you would write it like this:

$model = m::mock('model');
$model->shouldReceive('state')->andReturn($returnValue, $differentReturnValue);

It is obvious how much more beautiful the Mockery API is. It's an ode to readable code. It reads like text...

model should receive state and return values

You can add a constraint that the method has to be called exactly twice like so:

$model->shouldReceive('state')->twice()->andReturn($value, $differentValue);

If you want to pass arguments, it looks like this:

$model->shouldReceive('state')->withNoArgs()->andReturn($value)->once();
$model->shouldReceive('state')->with('saved')->andReturn($differentValue)->once();

Upvotes: 3

zerkms
zerkms

Reputation: 255155

$model = $this->getMock('Model');
$model->expects($this->at(0))
  ->method('state')
  ->will($this->returnValue('new'));
$model->expects($this->at(1))
  ->method('state')
  ->will($this->returnValue('saved'));
$model->expects($this->exactly(2))
  ->method('state');

http://www.phpunit.de/manual/3.6/en/test-doubles.html#test-doubles.mock-objects

Plus you can additionally check with with() that the parameter passed equals to saved

->with($this->equalTo('saved'))

PS: this will work for

public function foo($model)
{
  var_dump($model->state());
  var_dump($model->state('saved'));
}

For your code you need to set up 3 mock calls, not 2

Upvotes: 3

Related Questions