Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mock objects which support chaining methods

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.

like image 770
Nathan MacInnes Avatar asked Nov 20 '10 12:11

Nathan MacInnes


People also ask

How do you mock chain methods in jest?

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 };

What are mock methods?

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.

What is the purpose of using mock objects in test design?

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.

What is method chaining in selenium?

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.).


1 Answers

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()
        );
    }
}
like image 170
Gordon Avatar answered Sep 22 '22 21:09

Gordon