2011-02-23 144 views
4

近來爲了實現單元測試類的私有方法,我用PrivateObject通過創建一個私人的存取,而不是使用反射,而我收到了下面的代碼審查意見:在.NET中單元測試私有方法的最佳做法是什麼?

「我私人對象的主要關注點是在構造函數中使用object [],它取代了編譯器通過JavaScript風格運行時錯誤檢測強制執行的強類型。因此,我個人不會推薦它。

上面的這條評論令我困惑,因爲根據我的理解,反射也需要object[]來調用任何方法。請幫我理解最好的方法是什麼。

回答

2

你說得對,使用反射與使用PrivateObject模式有很多相同的缺陷。更好的解決方案是避免試圖專門測試私有方法。

+0

感謝您的回覆,我無法避免測試私有方法是它的要求。所以想通過正確理解 – 2011-02-23 06:00:13

4

有趣的問題。一般來說,單元測試是爲了從類的消費者角度來驗證你的類的公共行爲。也就是說,消費者不關心你如何做,只要你的班級遵守它的承諾。

如果您真的需要將'私人'成員公開爲單元測試,請將它們標記爲內部並通過InternalsVisibleTo屬性使它們可訪問。這很醜陋,但它起作用,並且稍後可以通過一些條件編譯將它保留在程序集外。

+0

來選擇反射和PrivateObject之間的內容......當然,將屬性,訪問器和方法標記爲內部意味着您完全信任另一個開發人員(或您未來的自己)在您的內部工作時要遵守這些規則assembly =) – anon 2011-02-23 05:56:50

+0

感謝您的回覆,我無法避免測試私有方法是它的要求。所以想通過正確理解在反射和PrivateObject之間選擇 – 2011-02-23 06:00:42

+0

@Chirag - 如果你有單元測試了所有的公共方法,你的私有方法將被隱式測試。那些沒有被你的單元測試覆蓋的私有方法是多餘的,應該被刪除。您測試私有方法*的要求可以通過測試公共方法來滿足。如果要求是你應該在單元測試中明確*調用私有方法,則需求是錯誤的*(我的觀點)*。 – 2011-02-23 08:03:12

6
  • 您可以使用特殊類, 繼承的類與私人(現 保護)的方法和提供公共 方法調用從 外面保護方法不可見的。

這就是所謂的測試特定的子類或大書測試特定擴展重構測試代碼http://xunitpatterns.com/

您可以閱讀在這裏測試私有方法的詳細信息和想法:http://xunitpatterns.com/Test-Specific%20Subclass.html

它就像

public TestClass : RealClass 
{ 
    public int CallHiddenCalculate() 
    { 
     return Calculate(); // Calculate is now protected method that we expose for test purposes in this class 
    } 
} 

您可以放置​​此類來測試程序集,以便您的真實程序集不包含特定於測試的邏輯和類,因爲它的ba d設計。

  • 您還可以使用條件編譯能見度屬性類似如下
 
    #if DEBUG 
     public 
    #else 
     private 
    #endif 

在這種情況下,調試就可以調用單元測試,但在發佈這些方法將不可見。 然而,這種方法比上述更糟糕,也更醜陋。

爲了說你有很好的測試覆蓋率並且你的代碼易於維護和重構,測試公共接口可能很不容易(通常也不是)。

至於標記私有方法的內部,並具有檢測組件看到內部方法是不好的原因有很多

  1. 你的前私有方法可見 從裝配的原因,他們是 內部
  2. 你將有測試具體邏輯 (對於那些方法的內部將 僅用於測試目的) 發佈版本您的產品, 這是不好的

,我想有更多,但這些都是最重要的

+0

+1 - 我喜歡它!這也可以擴展到受保護的訪問者!今天我學到了一種有用的技術。 – anon 2011-02-23 06:01:04

0

如果您使用的是Gallio/MbUnit測試框架,你可以考慮內置Mirror API。

有時,編寫測試最明顯的方法是訪問非公共狀態或行爲。這可能不是編寫測試的最佳方式,但它似乎是目前最簡單的解決方案。 MbUnit提供了幾個課程來幫助訪問非公開成員。

相關問題