2013-12-17 58 views
0

我怎樣才能創建一個模擬類(不只是一個模擬對象)返回值,條件是,當實例化將返回一個可預測值的方法?在下面的代碼中,我測試了一個更大的概念(accounts-> preauthorize()),但我需要模擬對象查找,以便我可以獲得可預測的結果以供測試使用。創建一個模擬類,其方法實例化時

我使用PHPUnit的和CakePHP,如果該事項。這裏是我的情況:

// The system under test 
class Accounts 
{ 
    public function preauthorize() 
    { 
     $obj = new Lookup(); 
     $result = $obj->get(); 
     echo $result; // expect to see 'abc' 
     // more work done here 
    } 
} 

// The test file, ideas borrowed from question [13389449][1] 
class AccountsTest 
{ 
    $foo = $this->getMockBuilder('nonexistent') 
     ->setMockClassName('Lookup') 
     ->setMethods(array('get')) 
     ->getMock(); 
    // There is now a mock Lookup class with the method get() 
    // However, when my code creates an instance of Lookup and calls get(), 
    // it returns NULL. It should return 'abc' instead. 

    // I expected this to make my instances return 'abc', but it doesn't. 
    $foo->expects($this->any()) 
     ->method('get') 
     ->will($this->returnValue('abc')); 

    // Now run the test on Accounts->preauthorize() 
} 

回答

3

這裏有幾個問題,但主要的問題是你在需要它的方法中實例化你的Lookup類。這使得它不可能嘲笑。您需要將查找實例傳遞給此方法以解耦依賴項。

class Accounts 
{ 
    public function preauthorize(Lookup $obj) 
    { 
     $result = $obj->get(); 
     return $result; // You have to return something here, you can't test echo 
    } 
} 

現在你可以模擬查找。

class AccountsTest 
{ 
    $testLookup = $this->getMockBuilder('Lookup') 
     ->getMock(); 

    $testLookup->expects($this->any()) 
     ->method('get') 
     ->will($this->returnValue('abc')); 

    $testAccounts = new Accounts(); 
    $this->assertEquals($testAccounts->preauthorize($testLookup), 'abc'); 
} 

不幸的是,我不能對此進行測試試驗,但這應該讓你在正確的方向前進。

顯然,對於Lookup類也應該存在一個單元測試。

您也可以找到我的一些使用的answer here

+0

我簡化了我的情況,使其更有意義。原來我簡化了它。你爲我簡化的例子提供了一個合理的解決方案,所以謝謝。但事實上,preauthorize()是一個CakePHP控制器,其參數來自客戶端,不能容納HttpSocket實例。 (我改名爲「Lookup」的實際上是CakePHP實用程序HttpSocket)。哎呀。謝謝,不過。 –

+0

我從未使用過的蛋糕,但我聽說它不是太好,只要現代的框架去。我會強調,不能孤立你的類來單元測試它們是一種代碼味道。很明顯,我無法判斷這些異味來自您的代碼還是來自您的框架。就我個人而言,我會花很長時間仔細研究我的架構。但是,我是一個單獨的開發人員,沒有人告訴我如何編寫代碼或使用什麼框架。祝你好運。 – vascowhite

+1

重新閱讀您的評論。在我遇到的所有框架中,單元測試控制器是不可能的,它不能與它的依賴隔離。我通過將盡可能多的邏輯移出控制器並進入模型或服務層來克服這一點,以便我的控制器儘可能地瘦。如果你還沒有這樣做,這可能是你想要考慮的一種策略。 – vascowhite

相關問題