Testing methods in abstract classes with arguments
In my TDD project I am trying to test a method in an abstract class.
abstract class Database_Mapper_Abstract
{
public function setTable($sTablename){
return('foo');
}
}
This is the way I wrote my simple test:
public function testCanSetTable(){
$oMock = $this->getMockForAbstractClass('JCMS_Database_Mapper_Abstract');
$oMock->expects($this->once())
->method('setTable')
->with($this->equalTo('foo'))
->will($this->returnValue('foo'));
$this->assertEquals('foo',$oMock->setTable());
}
When I run this test i get the following error:
PHPUnit 3.5.13 by Sebastian Bergmann.
E
Time: 1 second, Memory: 6.75Mb
There was 1 error:
1) Database_Mapper_AbstractTest::testCanSetTable Missing argument 1 for Database_Mapper_Abstract::setTable(), called in K:\xampp\htdocs\tests\library\Database\Mapper\Abstract.php on line 15 and defined
K:\xampp\htdocs\library\Database\Mapper\Abstract.php:4 K:\xampp\htdocs\tests\library\Database\Mapper\Abstract.php:15
FAILURES! Tests: 1, Assertions: 0, Errors: 1.
The way I understand this is that it can't find the argument for the setTable function.
But I set it with the with()
method. I also tried with('foo')
. That al开发者_运维百科so doesn't help me.
Does anyone have an idea?
Testing an abstract class:
For testing an abstract class you don't want to use the "create behavior methods".
Just getMockForAbstractClass()
like this:
<?php
abstract class JCMS_Database_Mapper_Abstract
{
public function setTable($sTablename){
return $sTablename."_test";
}
}
class myTest extends PHPUnit_Framework_TestCase {
public function testCanSetTable(){
$oMock = $this->getMockForAbstractClass('JCMS_Database_Mapper_Abstract');
$this->assertEquals('foo_test', $oMock->setTable('foo'));
}
}
You just use the mocking functionality to create an instance of that abstract class and test against that.
It's only a shortcut for writing
class MyDataMapperAbstractTest extends JCMS_Database_Mapper_Abstract {
// and filling out the methods
}
The actual error:
What happens is that you have a method with one parameter:
public function setTable($sTablename){
but you call it with zero paremters:
$oMock->setTable()
so you get an error from PHP and if PHP throws a warnings PHPUnit will show you an error.
Reproduce:
<?php
abstract class JCMS_Database_Mapper_Abstract
{
public function setTable($sTablename){
return('foo');
}
}
class myTest extends PHPUnit_Framework_TestCase {
public function testCanSetTable(){
$oMock = $this->getMockForAbstractClass('JCMS_Database_Mapper_Abstract');
$oMock->expects($this->once())
->method('setTable')
->with($this->equalTo('foo'))
->will($this->returnValue('foo'));
$this->assertEquals('foo',$oMock->setTable());
}
}
Results in:
phpunit blub.php
PHPUnit 3.5.13 by Sebastian Bergmann.
E
Time: 0 seconds, Memory: 3.50Mb
There was 1 error:
1) myTest::testCanSetTable
Missing argument 1 for JCMS_Database_Mapper_Abstract::setTable(), called in /home/.../blub.php on line 19 and defined
Fixing
Change:
$this->assertEquals('foo',$oMock->setTable());
to
$this->assertEquals('foo',$oMock->setTable('foo'));
then you don't get a PHP Warning and it should work out :)
精彩评论