2011-06-17 35 views
2

在我的TDD项目中,我试图在抽象类中测试一个方法。带参数的抽象类中的测试方法

abstract class Database_Mapper_Abstract 
{ 

    public function setTable($sTablename){ 
     return('foo'); 

    } 
} 

这是我写的我简单的测试方法:

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

当我运行这个测试,我得到以下错误:

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.

我明白这个问题的方法是,它找不到setTable函数的参数。 但我用with()方法设置它。我也试过with('foo')。这也没有帮助我。

有没有人有想法?

+1

我不知道这个测试框架,但如果你改变`$这个 - >的assertEquals(“富”发生了什么,$ oMock-> setTable());`to`$ this-> assertEquals('foo',$ oMock-> setTable('foo'));` – 2011-06-17 10:57:40

+0

在我看来,你不应该模拟被测试的类。因为上面的代码没有测试setTable方法是否会返回'foo',所以它*定义*方法setTable将返回'foo'。模拟对象用于将它们作为参数传递给测试中的类,因此不需要创建大对象图来满足依赖关系。 – 2011-06-17 10:59:20

回答

6

测试一个抽象类:

测试你不想使用“创建行为的方法”的抽象类。

getMockForAbstractClass()这样的:

<?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')); 
    } 

} 

你只用嘲讽的功能来创建一个抽象类和测试针对的一个实例。

这只是一个快捷方式编写

class MyDataMapperAbstractTest extends JCMS_Database_Mapper_Abstract { 
    // and filling out the methods 
} 

实际的错误:

什么情况是,你有一个参数的方法:

public function setTable($sTablename){ 

但你打电话它与零排序:

$oMock->setTable() 

所以你得到一个PHP的错误,如果PHP引发警告PHPUnit会告诉你一个错误。

重现:

<?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()); 
    } 

} 

结果:

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 

固定

变化:

$this->assertEquals('foo',$oMock->setTable()); 

$this->assertEquals('foo',$oMock->setTable('foo')); 

那么你没有得到一个PHP的警告,它应该工作了:)