开发者

Testing methods in abstract classes with arguments

开发者 https://www.devze.com 2023-03-13 20:38 出处:网络
In my TDD project I am trying to test a method in an abstract class. abstract class Database_Mapper_Abstract

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

0

精彩评论

暂无评论...
验证码 换一张
取 消