2011-02-25 176 views
1

首先我很抱歉如果問題已被問到,但我沒有找到像我的任何人(但我認爲這是一個相當普遍的問題) 所以我試圖做一些單元測試,和第一個已經成問題了。訪問私人字段

我必須測試我的類的構造函數,在構造函數中我設置了一個私有字段的實例。那麼如何測試這個PRIVATE字段是否不爲空呢? (因爲我想的是,我有什麼測試) - >測試:

public BUDGET_MANAGER() 
    { 
     this.budget_provider = new BUDGET_PROVIDER(); 
    } 

- >測試Mehod:

[TestMethod()] 
    public void BUDGET_MANAGERConstructorTest1() 
    { 
     BUDGET_MANAGER target = new BUDGET_MANAGER();  
     Assert.IsNotNull(??,"the provider is not instancied"); 

    } 

我該怎麼辦呢?感謝您的幫助,我迷上了單元測試。

+1

參見:http://msdn.microsoft.com/en-us/library /0tke9fxk.aspx(儘管你必須使字段「內部」而不是「private」,這可能不是你想要的。) – 2011-02-25 22:31:00

+0

[單元測試和檢查私有變量值](http:/ /stackoverflow.com/questions/1093020/unit-testing-and-checking-private-variable-value) – 2011-02-25 22:33:08

回答

4

在你的單元測試中,你真的不應該測試任何對於一個類是私有的東西。私有的,內部唯一的已知成員是類的實現的一部分,而不是其公開的(已測試的)功能的一部分。

基本上,把這個類的外部可見的成員想象成它的「契約」。這就定義了它的實際類型,其他所見。這就是被測試的功能。由於很好的理由,內部(私人)成員在班級之外並不知道,不同的班級可以以不同的私人成員以不同的方式實施相同的「合同」(或界面)。

您正在測試的是可見功能,合同或界面。

+0

好,那麼沒有什麼可以測試我的情況? – bAN 2011-02-25 22:35:12

+0

@bAN:取決於班級。如果「類型」(接口,隱式或顯式)與「類」(實現)緊密結合,那麼單元測試表明可能需要重新思考和重新考慮。將接口的概念與類分開,測試將變得更加明顯。 (順便說一句,這是一個積極的測試結果...確定有關可能需要更改的類的信息。)但是,回答是,沒有什麼可以測試私有成員。只有公共功能。 – David 2011-02-25 22:38:16

2

單元測試應該不是檢查私人數據。他們應該測試你的類的接口定義的行爲是否工作,與任何實現細節無關。

典型的測試會調用構造函數,然後調用公共屬性或方法並檢查結果是否如預期的那樣。以這種方式進行測試意味着如果稍後將實現更改爲(例如)僅在需要時才構造BudgetProvider,那麼所有測試仍然可以工作。諸如私有成員是否爲空的實現細節與你的類的客戶無關,因此不需要在你的單元測試中進行測試。

+0

我想你的意思是單元測試應該*不*檢查私人數據,不是?如果是的話,同意。 – Paul 2011-02-25 22:30:51

+0

@保羅:是的,謝謝!這就是我的意思。 – 2011-02-25 22:32:49

1

如果您使用mstest,請右鍵單擊原始類,然後按創建測試訪問器,選擇您的測試項目。然後使用訪問器測試此條件(應顯示爲intellisense)。

雖然我不確定它是一個非常好的主意,正如其他海報所說的那樣。你會讓實施變得更加困難。

1

你不應該真的測試你的類的任何私有變量。

爲什麼你想測試構造函數本身?如果有一些邏輯,測試它是有意義的。例如 - 如果給定的參數是正確的,並且在創建對象之前進行驗證,則只構造該對象。否則,構建該對象並驗證其行爲如預期。據推測,如果構造函數工作不正確,對象的行爲也將不正確。

也抵制暴露專用字段作爲屬性的誘惑,以驗證它們是否在構造函數中正確設置。

+0

好的謝謝,並在此構造函數中設置值(構造函數參數)給私人budget_provider的情況下,我是否模擬了budget_provider以測試是否在budget_provider上調用了一個集合? – bAN 2011-02-25 22:42:23

+0

是的。這是一個非常好的方法 - 測試類和它的依賴關係(budget_provider)的交互。您可以根據對象的狀態檢查預期的交互是否發生。 – mfloryan 2011-02-26 11:57:47

0

其他人提到你使用單元測試時不應該做的事情。

我會試着找到一種方法,做你想做的(你還需要測試你的構造函數):

public BUDGET_MANAGER() 
{ 
    try 
    { 
     this.budget_provider = new BUDGET_PROVIDER(); 
    } 
    catch {} 

    if (this.budget_provider == null) 
     throw new NullReferenceException("Budget provider is null !"); 
} 
+0

沒有冒犯,但這是荒謬的。除非CLR被破壞,否則「new」不能返回null。例如:給我寫一個測試,說明拋出這個異常。 – bryanbcook 2011-02-26 13:35:37

+0

默認情況下,您應該將代碼塊視爲「僞代碼」。如您所見,原始問題也存在同樣的問題,但我們假設他已將案例簡介爲可讀性。如果它讓你開心,我在'new'關鍵字上添加了一個'try/catch'。 – Xaqron 2011-02-26 15:22:28