2011-06-17 70 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的警告,它應該工作了:)