Layout of objects that support chaining methods

I am wondering if there is a fairly concise way of mocking objects that support a chain of methods ... so, for example, a database query object may have a method call that looks like this:

$result = $database->select('my_table')->where(array('my_field'=>'a_value'))->limit(1)->execute(); 

The problem arises if I have to scoff at two different queries to choose from so that they return different results. Any ideas?

This is especially true for PHPUnit, but the experience of other structural testing modules will help.

+7
php unit-testing mocking phpunit
source share
3 answers

I'm not sure if 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() ); } } 
+14
source share

I know his old question, but it can help more googler's future.

I also had trouble finding a framework that would provide a simple and easy syntax for bullying and chaining nodes. then I decided to write a simple and easy-to-use library.

Usage example:

  // Creating a new mock for SimpleClassForMocking $mock = ShortifyPunit::mock('SimpleClassForMocking'); ShortifyPunit::when($mock)->first_method() ->second_method(2,3)->returns(1); ShortifyPunit::when($mock)->first_method() ->second_method(2,3,4)->returns(2); ShortifyPunit::when($mock)->first_method(1) ->second_method(2,3,4)->returns(3); ShortifyPunit::when($mock)->first_method(1,2,3) ->second_method(1,2)->third_method()->returns(4); $mock->first_method()->second_method(2,3); // returns 1 $mock->first_method()->second_method(2,3,4); // returns 2 $mock->first_method(1)->second_method(2,3,4); // returns 3 $mock->first_method(1,2,3)->second_method(1,2)->third_method(); // return 4 

Github:

https://github.com/danrevah/ShortifyPunit#stubbing-method-chanining

+1
source share

This may not be the answer you are looking for, but a couple of years ago I wrote a fake object structure that will handle this input-dependent view:

http://code.google.com/p/yaymock/

http://code.google.com/p/yaymock/wiki/Expectations

I wrote it for use in unit tests that support Swift Mailer, but it has not been widely accepted by other projects (of which I know). The goal was to provide better control and introspection of fictitious object calls than PHPUnit and SimpleTest.

0
source share

All Articles