PHPUnit is a xUnit framwork for PHP. It's written by Sebastian Bergmann.
I'll describe some problems and solutions when working with PHPUnit
If we want to write a Database Mock test to test the following code, we may want to check if invoke() calls the database object with the correct parameters.
Here we want to check if first param is SELECT id FROM books WHERE name = „Bible“ and the 2nd is id. Such an example could not be found in PHPUnit Pocketguide, but here ;)
class Testable { private $db; function __construct(Database $db) // DB obj is injected via constructor { $this->db = $db; } public function invoke() { // delegating call to db obj return $this->db->getField( 'SELECT id FROM books WHERE name = "Bible"', 'id'); } }
This code works. It really checks if everything is right.
class BugTest extends PHPUnit_Framework_TestCase { protected $db; // mockDB function setUp() { // create Database Mock, do not call original DB::_constructor $this->db = $this->getMock('Database', // class to mock up array(), // use these methods (all) array(), // original constr. arguments '' , // alt class name false); // call original constr? } /** * @group mockdb */ function testInvoke() { $retval = 2; // say phpunit what we expect $this->db->expects($this->once()) ->method('getField') ->with( /* IMPORTANT: use logicalAnd(), logicalAnd() to combine arguments here! */ $this->logicalAnd( $this->equalTo('SELECT id FROM books WHERE name = "Bible"')), $this->logicalAnd($this->equalTo('id')) ) ->will($this->returnValue($retval)); $testObj = new Testable($this->db); $this->assertEquals( $retval, $testObj->invoke()); } }
This is the code I wrote first. It's shown here just as an bad example. This test is more often true than it should!
DO NOT USE IT
part of test code
function testInvoke() { $retval = 2; // say phpunit what we expect $this->db->expects($this->once()) ->method('getField') ->with( // in my first test I tried to use normal 'and' $this->equalTo('SELECT id FROM books WHERE name = "Bible"') and $this->equalTo('id') ) ->will($this->returnValue($retval)); $testObj = new Testable($this->db); $this->assertEquals( $retval, $testObj->invoke()); }