2010-09-28 54 views
3

我正在研究phpunit中的測試,並且遇到了一個問題。我在我的課上有一個公共職能,我正在測試。根據傳遞給方法的參數,我的測試類中的受保護函數將被調用一次或兩次。我目前有一個測試來檢查返回數據是否正確,但我還想確保被保護的方法被調用正確的次數。PHPUnit測試函數被稱爲多少次

我知道一個模擬對象將允許我計算函數被調用的次數,但它也會覆蓋受保護函數返回的值。我試着使用一個沒有「will」部分的模擬對象,但它只會返回null,而不是保護方法的實際值。

ExampleClass中

public function do_stuff($runTwice){ 
$results = do_cool_stuff(); 
    if($runTwice){ 
    $results = 2 * do_cool_stuff(); 
    } 
    return $results; 
} 

protected function do_cool_stuff() 
{ 
    return 2; 
} 

在我的測試,我想檢查do_cool_stuff()是否被調用一次或兩次,但我還是想兩個函數的返回值是一樣的,所以我可以測試這些作爲以及在我的單元測試中。

tl; dr 我想統計測試對象中被保護方法的調用次數(就像你可以用模擬對象做的那樣),但我仍然希望我的測試方法中的所有方法都返回它們的正常值值(不像模擬對象)。

回答

1

嘗試在使用該類之前設置一個全局變量。

$IAmDeclaredOutsideOfTheFunction; 

然後用它來存儲計數,並簡單地在您的函數和類被調用後檢查它。

4

或者,還原爲您自己的可測試替身。以下aint相當不錯,但你有這個想法:

class ExampleClass { 
    public function do_stuff($runTwice) { 
     $results = $this->do_cool_stuff(); 
     if ($runTwice) { 
      $results = 2 * $this->do_cool_stuff(); 
     } 
     return $results; 
    } 

    protected function do_cool_stuff() { 
     return 2; 
    } 
} 

class TestableExampleClass extends ExampleClass { 
    /** Stores how many times the do_cool_stuff method is called */ 
    protected $callCount; 

    function __construct() { 
     $this->callCount = 0; 
    } 

    function getCallCount() { 
     return $this->callCount; 
    } 

    /** Increment the call counter, and then use the base class's functionality */ 
    protected function do_cool_stuff() { 
     $this->callCount++; 
     return parent::do_cool_stuff(); 
    } 
} 


class ExampleClassTest extends PHPUnit_Framework_TestCase { 

    public function test_do_stuff() { 
     $example = new ExampleClass(); 
     $this->assertEquals(2, $example->do_stuff(false)); 
     $this->assertEquals(4, $example->do_stuff(true)); 
    } 

    public function test_do_cool_stuff_is_called_correctly() { 
     // Try it out the first way 
     $firstExample = new TestableExampleClass(); 
     $this->assertEquals(0, $firstExample->getCallCount()); 
     $firstExample->do_stuff(false); 
     $this->assertEquals(1, $firstExample->getCallCount()); 

     // Now test the other code path 
     $secondExample = new TestableExampleClass(); 
     $this->assertEquals(0, $secondExample->getCallCount()); 
     $secondExample->do_stuff(true); 
     $this->assertEquals(2, $secondExample->getCallCount()); 
    } 
} 

我想知道是否計算一個被保護的方法被調用的次數真的是一個很好的測試。它很難將你的測試與實現結合起來。它是否被稱爲兩次真的很重要,還是你對與其他對象的交互更感興趣?或者,也許這是指向do_cool_stuff需要重構成兩個單獨的方法:

class ExampleClass { 
    public function do_stuff($runTwice) { 
     if ($runTwice) { 
      return $this->do_cool_stuff_twice(); 
     } else { 
      return $this->do_cool_stuff_once(); 
     } 
    } 
    //... 
}