I'm wondering if there's a fairly concise way of mocking objects which support chaining of methods... so for example, a database query object might have a method call that looks like this:
$result = $database->select('my_table')->where(array('my_field'=>'a_value'))->limit(1)->execute();
The problem comes if I have to mock two different select queries so that they return different results. Any ideas?
This is specifically about PHPUnit, but experiences from other unit testing frameworks will help.
You can use mockFn. mockReturnThis() to do this. const client = { items: () => { return client; }, type: (name: string) => { return client; }, toObservable: () => { return client; }, subscribe: handler => { handler(); return client; } }; export { client };
Mocking is done when you invoke methods of a class that has external communication like database calls or rest calls. Through mocking you can explicitly define the return value of methods without actually executing the steps of the method.
Using mock objects allows developers to focus their tests on the behavior of the system under test without worrying about its dependencies. For example, testing a complex algorithm based on multiple objects being in particular states can be clearly expressed using mock objects in place of real objects.
Method Chaining is the practice of calling different methods in a single line instead of calling other methods with the same object reference separately. Under this procedure, we have to write the object reference once and then call the methods by separating them with a (dot.).
I am not sure this is what you are looking for, so please leave a comment:
class StubTest extends PHPUnit_Framework_TestCase
{
public function testChainingStub()
{
// Creating the stub with the methods to be called
$stub = $this->getMock('Zend_Db_Select', array(
'select', 'where', 'limit', 'execute'
), array(), '', FALSE);
// telling the stub to return a certain result on execute
$stub->expects($this->any())
->method('execute')
->will($this->returnValue('expected result'));
// telling the stub to return itself on any other calls
$stub->expects($this->any())
->method($this->anything())
->will($this->returnValue($stub));
// testing that we can chain the stub
$this->assertSame(
'expected result',
$stub->select('my_table')
->where(array('my_field'=>'a_value'))
->limit(1)
->execute()
);
}
}
You can combine this with expectations:
class StubTest extends PHPUnit_Framework_TestCase
{
public function testChainingStub()
{
// Creating the stub with the methods to be called
$stub = $this->getMock('Zend_Db_Select', array(
'select', 'where', 'limit', 'execute'
), array(), '', FALSE);
// overwriting stub to return something when execute is called
$stub->expects($this->exactly(1))
->method('execute')
->will($this->returnValue('expected result'));
$stub->expects($this->exactly(1))
->method('limit')
->with($this->equalTo(1))
->will($this->returnValue($stub));
$stub->expects($this->exactly(1))
->method('where')
->with($this->equalTo(array('my_field'=>'a_value')))
->will($this->returnValue($stub));
$stub->expects($this->exactly(1))
->method('select')
->with($this->equalTo('my_table'))
->will($this->returnValue($stub));
// testing that we can chain the stub
$this->assertSame(
'expected result',
$stub->select('my_table')
->where(array('my_field'=>'a_value'))
->limit(1)
->execute()
);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With