How to Get PHPunit Mockobjects to Return Different Values Based on a Parameter

How can I get PHPUnit MockObjects to return different values based on a parameter?

Use a callback. e.g. (straight from PHPUnit documentation):

<?php
class StubTest extends PHPUnit_Framework_TestCase
{
public function testReturnCallbackStub()
{
$stub = $this->getMock(
'SomeClass', array('doSomething')
);

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

// $stub->doSomething() returns callback(...)
}
}

function callback() {
$args = func_get_args();
// ...
}
?>

Do whatever processing you want in the callback() and return the result based on your $args as appropriate.

PHPUnit vary mock method return value based on arguments

You can use returnValueMap to change the value that is being returned by your mock.

https://phpunit.de/manual/current/en/test-doubles.html#test-doubles.stubs.examples.StubTest5.php

This method takes an array of which the first n values are the arguments being used and the last value is the return value.

So your mock would look like this:

$map = [
[ SESSION_FILTER_MONTH, '2017-05'],
[ SESSION_FILTER_FUND, 'test_return_fund']
];

$container->get('session')
->method('get')
->will($this->returnValueMap($map));

PHPUnit Different return values every call of mocked method

$mock->expects($this->any())
->method("someMethod")
->will($this->onConsecutiveCalls(1, 2, 3));

With onConsecutiveCalls you can set a return value for every call of someMethod. The first call returns 1. The second call 2. The third call 3.

phpunit mock method multiple calls with different arguments

The PHPUnit Mocking library (by default) determines whether an expectation matches based solely on the matcher passed to expects parameter and the constraint passed to method. Because of this, two expect calls that only differ in the arguments passed to with will fail because both will match but only one will verify as having the expected behavior. See the reproduction case after the actual working example.


For you problem you need to use ->at() or ->will($this->returnCallback( as outlined in another question on the subject.

Example:

<?php

class DB {
public function Query($sSql) {
return "";
}
}

class fooTest extends PHPUnit_Framework_TestCase {

public function testMock() {

$mock = $this->getMock('DB', array('Query'));

$mock
->expects($this->exactly(2))
->method('Query')
->with($this->logicalOr(
$this->equalTo('select * from roles'),
$this->equalTo('select * from users')
))
->will($this->returnCallback(array($this, 'myCallback')));

var_dump($mock->Query("select * from users"));
var_dump($mock->Query("select * from roles"));
}

public function myCallback($foo) {
return "Called back: $foo";
}
}

Reproduces:

phpunit foo.php
PHPUnit 3.5.13 by Sebastian Bergmann.

string(32) "Called back: select * from users"
string(32) "Called back: select * from roles"
.

Time: 0 seconds, Memory: 4.25Mb

OK (1 test, 1 assertion)




Reproduce why two ->with() calls don't work:

<?php

class DB {
public function Query($sSql) {
return "";
}
}

class fooTest extends PHPUnit_Framework_TestCase {

public function testMock() {

$mock = $this->getMock('DB', array('Query'));
$mock
->expects($this->once())
->method('Query')
->with($this->equalTo('select * from users'))
->will($this->returnValue(array('fred', 'wilma', 'barney')));

$mock
->expects($this->once())
->method('Query')
->with($this->equalTo('select * from roles'))
->will($this->returnValue(array('admin', 'user')));

var_dump($mock->Query("select * from users"));
var_dump($mock->Query("select * from roles"));
}

}

Results in

 phpunit foo.php
PHPUnit 3.5.13 by Sebastian Bergmann.

F

Time: 0 seconds, Memory: 4.25Mb

There was 1 failure:

1) fooTest::testMock
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-select * from roles
+select * from users

/home/.../foo.php:27

FAILURES!
Tests: 1, Assertions: 0, Failures: 1

PHPunit: How to mock a method that has a parameter AND a returned value

You need to use will instead of with for returnValue and friends.

$user->expects($this->once())
->method('removeItem')
->with($item) // equalTo() is the default; save some keystrokes
->will($this->returnValue(true)); // <-- will instead of with
$this->assertTrue($hoard->removeItemFromUser($item, $user));

How to return the argument of a mocked method?

As per the PHPUnit manual:

$stub->expects($this->any())
->method('doSomething')
->will($this->returnArgument(0));

How can I test if same method is called with correct parameters with PHPUnit and mock object

I don't know your mocking framework. Usually you just create another expectation though. I assume that should work with this framework as well.

$logMock->expects($this->exactly(1))
->method('updateLog')
->with(100, 'something else');

Edit

It seems that the PHPUnit framework doesn't support multiple different expectations on the same method. According to this site you have to use the index functionality.

It would then look like this

$logMock->expects($this->at(0))
->method('updateLog')
->with(456, 'some status');
$logMock->expects($this->at(1))
->method('updateLog')
->with(100, 'something else');
$logMock->expects($this->exactly(2))
->method('updateLog');

Getting different consecutive values on php mockery

From the section Declaring Return Value Expectations:

It is possible to set up expectation for multiple return values. By
providing a sequence of return values, we tell Mockery what value to
return on every subsequent call to the method:

$mock = \Mockery::mock('MyClass');
$mock->shouldReceive('name_of_method')
->andReturn($value1, $value2, ...)

The first call will return $value1 and the second call will return
$value2.

How to test a second parameter in a PHPUnit mock object

I believe the way to do this is:

$observer->expects($this->once())
->method('method')
->with($this->equalTo($arg1),$this->equalTo($arg2));

Or

$observer->expects($this->once())
->method('method')
->with($arg1, $arg2);

If you need to perform a different type of assertion on the 2nd arg, you can do that, too:

$observer->expects($this->once())
->method('method')
->with($this->equalTo($arg1),$this->stringContains('some_string'));

If you need to make sure some argument passes multiple assertions, use logicalAnd()

$observer->expects($this->once())
->method('method')
->with($this->logicalAnd($this->stringContains('a'), $this->stringContains('b')));

In PHPUnit, how do I indicate different with() on successive calls to a mocked method?

You need to use at():

$mock->expects($this->at(0))
->method('foo')
->with('someValue');

$mock->expects($this->at(1))
->method('foo')
->with('anotherValue');

$mock->foo('someValue');
$mock->foo('anotherValue');

Note that the indexes passed to at() apply across all method calls to the same mock object. If the second method call was to bar() you would not change the argument to at().



Related Topics



Leave a reply



Submit