2016-09-27 65 views
0

我想要做的事:創建一個不執行__constructor()的Mock對象,但是它有編碼的所有方法(沒有被模擬爲返回null)。使用PHPUnit中的模擬對象測試實際的類方法

The docs說:

「默認情況下,原始類的所有方法都替換爲 虛擬實現,只是返回null(不調用 原始方法)使用will($this->returnValue())方法,爲 。實例中,您可以配置這些虛擬實現以在調用時返回 值。「

這不是我想要的。我不想強制一種方法返回已知的值。我想測試方法本身,因此需要一個正常運行的類的實例化,但是使用禁用的構造函數。

我該怎麼做?

+0

這真的引出了一個問題:爲什麼你不想執行構造函數?通常情況下,這只是您必須執行的功能,必須以書面形式執行,以便正確設置對象以測試課程。 Mock對象用於所述類的依賴關係,以便能夠在不涉及第三方系統或其他業務代碼的情況下對其進行適當測試。 – ChristianF

回答

0

我爲類本身編寫測試用例,返回給定參數所需的數據,而不使用Mocks。 Mocks是用於這個類的外部引用,它需要知道函數Bar()返回Foo,所以等待該響應的類正確處理結果。

鑑於這種很乾脆的PHP類:

<?php 
class CATEGORY_SCOPE 
{ 
    public $CategoryName; 
    public $CategoryNo; 

    function __construct($CategoryNo = NULL, $CategoryName = NULL) 
    { 
     $this->CategoryName = $CategoryName; 
     $this->CategoryNo = $CategoryNo; 
    } 

    protected function SetCategoryName($Name) 
    { 
     $this->CategoryName = Name; 
    } 
} 
?> 

我將對其進行測試:

<?php 
require_once(substr(__FILE__, 0, -5)); // strip '.test' extension 
class TEST_CATEGORY_SCOPE extends PHPUnit_Framework_TestCase 
{ 
    protected function setUp() 
    { 
    } 

    public function testObjectCreation() 
    { 
     $CategoryInfo = new CATEGORY_SCOPE(); 
     $this->assertInstanceOf('CATEGORY_SCOPE', $CategoryInfo); 
    } 

    public function testConstructFieldOrder() 
    { 
     $CategoryInfo = new CATEGORY_SCOPE(1500, 'Category Name'); 
     $this->assertEquals(1500, $CategoryInfo->CategoryNo); 
     $this->assertEquals('Category Name', $CategoryInfo->CategoryName); 
    } 

    public function testConstructDefaults() 
    { 
     $CategoryInfo = new CATEGORY_SCOPE(); 
     $this->assertNull($CategoryInfo->CategoryNo); 
     $this->assertNull($CategoryInfo->CategoryName); 
    } 

    public function testSetCategoryName() 
    { 
     $CategoryInfo = new CATEGORY_SCOPE(); 
     $CategoryInfo->SetCategoryName('New Name'); 
     $this->assertEquals('New Name', $CategoryInfo->CategoryName); 
    } 
} 
?> 

這會對測試的類本身的工作,而且我可以設置一定的值。顯然這是一個簡單的例子。現在,當有些東西使用這個類時,我仍然可以通過目錄測試字段設置,但是這裏已經介紹了。

對於你的問題,假設我有類FOO(),它接受CATEGORY_SCOPE作爲構造函數中的一個參數。您可以模擬CATEGORY_SCOPE類,並設置內部Bar()函數以返回某些數據,而不管CATEGORY_SCOPE類的處理如何。

<?php 
class FOO 
{ 
    public $ReturnValue 
    function __construct($CategoryScope) 
    { 
     $this->ReturnValue = $CategoryScope->Bar(); 
    } 
} 
?> 

通過嘲諷CATEGORY_SCOPE類,這樣的酒吧()函數總是返回5(有些價值是有道理的,以你的代碼),然後你可以測試Foo類按預期工作。

<?php 
require_once(substr(__FILE__, 0, -5)); // strip '.test' extension 
class TEST_FOO extends PHPUnit_Framework_TestCase 
{ 
    protected function setUp() 
    { 
    } 

    public function testObjectCreation() 
    { 
     $FooInfo = new FOO(); 
     $this->assertInstanceOf('FOO', $FooInfo); 
    } 

    public function testFoo() 
    { 
     // Set Up the Mock so Bar() returns 5 using your mock library 

     ... <- Actual code for the mock goes here 

     $FooInfo = new FOO($CategoryMock); 
     $this->assertEquals(5, $FooInfo->Bar()); 
    } 
} 
?>