2013-07-30 54 views
0

我對私有/受保護方法的測試存在疑問。這是一個解決任何平臺單元測試的普遍問題。但只是告訴你,我正在與phpunit一個單元測試php的平臺。我應該測試私有/受保護的方法嗎?爲什麼?

我們應該測試私有/受保護的方法嗎?這個question接受的答案說,我們通常不應該。 從這個問題的答案:

通常你只是不測試或嘲笑的私人&保護方法directy。

你想測試的是你的類的公共API。其他一切都是爲您的課程提供的 實施細節,如果您更改它,則不會「破壞」您的測試。

但在這麼多的問題,同時其他的答案提供了一種方法來測試他們(我假定這些答案意味着我們應該測試私有/保護的方法,因爲他們不說,我們應該或不應該對其進行測試)。

請解釋我的理由。謝謝。

+0

我已投票結束主要是基於意見的。我認爲這會在沒有事實答案的情況下引發太多爭論。 –

+0

有很多關於如何做錯事的問題(和答案)...... :) –

+0

@DuncanJones好的。然後,如果我有這個疑問,我請你建議我該怎麼做。 – Geek

回答

1

至於我 - 它取決於私人/受保護成員的複雜性。

例如你有一個複雜的計算私有方法FUNC1()和FUNC2()或多個輸入參數的算法。你有一個使用它們的公共API。和一些數據FUNC1()被打破,並返回不正確的數據,但在FUNC2加工過程中()這個數據在某種程度上轉化爲正確的結果(如其他問題的結果)。公共API方法的總結果將是正確的 - 這意味着您有錯誤Func1Func2但您的API retors正確地以某種方式糾正。你試了一下,沒問題。

現在你給你的代碼給別人,和他/她創造FUNC3()和使用FUNC1()和FUNC3()多了一個公共的API方法和單元測試這個API方法失敗。他/她花費多少時間才能發現原因在Func1?並且當Func1將被修復時,您將在之前的測試中使用Func2失敗......這總的來說並不好。

因此,恕我直言,你應該測試私有/受保護的方法,如果他們是複雜的(很多代碼或使用不明顯的算法)和可重複使用。當然,您不需要爲返回+ b或編寫調試日誌記錄的私有方法創建100個單元測試。

希望我的回答能幫助你! 最好的問候,米哈伊爾。

0

相信的私人/受保護的方法測試取決於在哪裏/如何被訪問,什麼正在測試。

如果我建立的公共代碼可重用庫,那麼這些類中的private和protected方法庫的測試用例中測試。這些測試確保較低級別的代碼可以正常工作,以便我可以對圖書館有信心。

現在,當我寫訪問這個庫業務應用程序,我不寫的庫對象的測試,因爲他們將在業務應用測試被嘲笑。圖書館測試表明圖書館工作,然後商業應用程序測試顯示該應用程序工作。

業務應用程序不會嘗試測試庫的私營/保護方法,因爲我認爲的代碼一個黑盒子,我不知道(類似於外部庫或Web服務)。然而,我仍然在業務應用程序的測試套件中測試業務應用程序的私有和受保護的方法,以確保方法/函數的行爲與他們應該的一樣。

作爲一個例子吧,假設以下業務類(非常簡短的表達思想,而不是函數):

<?php 
class ACCOUNTS 
{ 
    protected GetEstimation() 
    { 
     ... 
     return $CalculatedValue; 
    } 
} 

class CUSTOMER_ACCOUNT extends ACCOUNTS 
{ 
    protected GetEstimation() 
    { 
     $BaseEstimation = parent::GetEstimation(); 
     ... 
     return $NewCalculatedValue 
    } 
} 

class RESELLER_ACCOUNT extends ACCOUNTS 
{ 
    protected GetEstimation() 
    { 
     ... 
     return $ResellerCalculatedValue; // Note: No call to parent 
    } 
} 
?> 

在這個例子中有一些將要返回不同的值。 Protected功能被使用,因此可以被覆蓋,並且不必依賴父類功能。在這個例子中,我想測試所有這些類在使用時返回正確的值。

的基本賬戶類應該儘自己的計算,基於類值後返回的估計。作爲一個規則,我只是設置的值和測試的回報:

<?php 
class ACCOUNTSTest extends PHPUnit_Framework_TestCase 
{ 
    protected $Accounts; 

    protected function setUp() 
    { 
     $this->Accounts = new ACCOUNTS(); 
    } 

    public function testEstimationHome() 
    { 
     $this->Accounts->InternalValue1 = 1; 
     $this->Accounts->InternalValue2 = 10; 
     $this->Accounts->InternalValue3 = 100; 
     $this->assertEquals(523, $this->Accounts->GetEstimation(), 'Test Home Account with values 1, 10, 1000'); 
    } 

    public function testEstimationHome2() 
    { 
     $this->Accounts->InternalValue1 = 5; 
     $this->Accounts->InternalValue2 = 2; 
     $this->Accounts->InternalValue3 = 10; 
     $this->assertEquals(253, $this->Accounts->GetEstimation(), 'Test Home Account with values 5, 2, 10'); 
    } 

    protected function tearDown() 
    { 
     unset($this->Accounts); 
    } 
} 
?> 

現在,這些測試將確保ACCOUNTS-> GetEstimation()是否正常工作。然後我會測試CUSTOMER_ACCOUNT,並進行類似的測試以確保該類正確計算。是的,如果基類發生變化,那麼我可能需要更新CUSTOMER_ACCOUNT中的測試,因爲ACCOUNTS-> GetEstimation()發生了變化,但是我還有一個額外的檢查,即基類仍然正確返回。

或者,我可以改變這個結構,使用依賴注入提供某些信息(賬戶),以確保如果父估計總是523,那麼這個類返回正確的價值觀。如果ACCOUNTS改變了返回的估計值,並且對這個類無關緊要(也許這個類只是增加了額外的值),然後我將我的測試隔離開來,不用擔心。

希望這個更新有助於說明我在說什麼。

+0

謝謝你的回答。我明白爲什麼我們不需要測試庫。但是,您能否詳細說明爲什麼我們應該測試私有/受保護的業務應用方法? – Geek

+0

商業應用程序仍然需要工作。許多應用程序類使用私有/受保護的,所以外部類不能更改這些值。但是,如果我在類方法中做了不重要的工作(並且它可能是私有的),那麼我想確保該類經過測試並且該方法不會更改。我發佈了一個僞示例作爲解答這個問題的答案。 –

1

私有和受保護的方法是被測代碼的實現細節,不應該被測試。你的測試告訴你「你的代碼應該做什麼」。測試私有和受保護的方法開始進入你的代碼應該做什麼的「如何」。

當你修改你的類,因爲你發現了一些代碼重用,你有沒有測試,你知道,那是因爲你改變了一些功能和需要修復的測試用例添加一些私有方法。如果您對私有和受保護的方法進行了測試,並且您現在做了同樣的事情,那麼您需要查看測試是否由於某個有效原因而失敗,或者來自您的重新分解。私有和受保護的方法通過類的公共接口的測試覆蓋,不需要任何測試。

只因爲你「可以」做的東西並不意味着你「應該」做一些事情。

當我測試時,我認爲被測系統是一個黑盒子。我給它一些東西,我希望發生一些事情。我不在乎裏面發生了什麼。所有重要的是給出正確的輸出。

複雜的內部函數是一種代碼味道,也許我有我的課做得太多,可能有另一個類隱藏在裏面。

相關問題