2012-02-07 68 views
1

首先,我知道有很多關於這個話題的問題。我讀過其中的大部分,但我真的不知道它是否缺乏適當的面向對象編程,或者我是否缺少一些東西。單元測試專用方法

所以我有一個類xmlRead,它將XML文件讀入一些列表。我想單元測試這個類。我認爲最簡單的方法就是測試addDataToList()。但這是一種私人方法。所以我想知道是否應該公開它,或者測試公共方法ReadTheXmlFile()。

public class xmlRead 
{ 
    List<string> ... // A couple of lists that need to filled with data from the XML document 
    xmlDocument xDoc = new xmlDocument 

    public void ReadTheXmlFile() 
    { 
     // Find default file, if it doesn't exist, ask user for file through Openfiledialog 
     // and open XMLDocument + error handling if XMLdocument is empty etc. 
     xDoc.load(filepath); 
     takeInXmlData(); 
    } 

    private void takeInXmlData() 
    { 
     addDataToList(list<string> list1, xmlNode 1); 
     // More addDataToList for different lists 
     ... 
     addDataToList(list<string> list2, xmlNode 2); 
    } 

    private void addDataToList(list<string> inputList, xmlNode) 
    { 
     foreach (XmlNode node in xmlDoc.SelectNodes(xmlNode)) 
     { 
      inputList.Add(node.SelectSingleNode("Specific name of node").InnerText); 
     } 
    } 

所以我儘量分開東西。但這也意味着我的方法addDataToList非常小,但容易進行單元測試。但我也覺得它不應該是一種公開的方法。我當然可以測試公共方法ReadTheXmlFile(),但是我必須爲每個錯誤檢測結果做出特定的測試用例,並且在我看來,我不會正確測試數據到列表中的實際攝入量。

我是否過於保護,是否應該讓addDateToList(或takeInXmlData)公開?或者我應該只是測試公共方法ReadTheXmlFile,直到我考慮所有可能的方式?

它只是感覺像很多工作,這種做法違背了簡單單元測試的原則。 PS:不需要擔心我直接在這裏加載xDoc的事實,我有一個管理XML文檔加載的接口(我可以稍後存根來打破依賴關係)。重點是在這裏的私人方法。

+0

你應該不需要測試私有方法,如果它們很複雜,那麼設計需要再次查看。 – luketorjussen 2012-02-07 10:58:00

+0

就是這樣,他們不是。他們就像3-4行代碼。因此,我爲什麼要測試它們。他們被稱爲「很多」。因此,我打破了一些我會立即知道的單元測試。 – 2012-02-07 11:00:30

回答

1

您的addDateToList方法是實現細節。你想要和應該測試的是ReadTheXmlFile方法。你甚至已經發現了什麼應該被測試:

查找默認的文件,如果它不存在,詢問用戶通過打開文件對話框的文件和開放的XMLDocument +錯誤處理如果XmlDocument的是空等

  • 測試時,發現失敗會發生什麼(這聽起來像外部dependecy工作壽)
  • 測試錯誤處理
  • 測試XML文檔是空
  • 測試PROPERT XML是在成功返回(這將暗示測試私有方法)

而這一點:

我當然可以測試公衆方法ReadTheXmlFile(),但後來我不得不爲每個錯誤檢測結果制定特定的測試用例,並且我認爲我不會將實際的數據吸收量列入清單。

這就是你應該做的。如果你的方法有多個可能的錯誤結果,每個都應該被測試。它沒有比這更簡單。大多數框架通過NUnit的TestCase等屬性可以很容易地實現這種(多輸入/輸出測試)。

在旁註中,如果您發現自己非常需要測試私有方法,那麼通常指示您的類正在做太多的東西,並且將私有方法的功能提取到外部對象可能值得考慮。

3

您可以使用InternalsVisibleTo屬性允許單元測試查看您的方法,同時保持世界其他地方的私密性。

+0

我不知道那個。謝謝(你的)信息! – 2012-02-07 10:47:32

+0

是的,但請記住,方法必須標記爲內部而不是私有。 – 2012-02-07 10:52:26

3

反射允許您調用私有方法,並從類的外部讀取或寫入私有字段,但寫入非常冗長。

在C#4.0中,可以使用動態類型以一種整潔的方式解決此問題。

如果你可以用在單元測試中使用C#4.0,看看這篇文章:

Testing private methods with C# 4.0

一個簡單的用法:

public class Service { 
    private int Step1() { 
     return 1; 
    } 
} 

[TestClass] 
public class TransparentObjectTests { 
    [TestMethod] 
    public void PrivateMethod() { 
     dynamic s = new Service().AsTransparentObject(); 
     Assert.AreEqual(1, s.Step1()); 
    } 
} 
+1

很好的答案,我終於得到了這個https://github.com/Cognifide/ExposedObject – fifth 2013-03-06 09:11:01

0

你可以試試,

開放AssemblyInfo.cs文件。添加該代碼,

[assembly: InternalsVisibleTo("Your Test Library Name")] 

然後,更改私人 - 到 - 內部

你可以寫測試中XmlRead類的內部方法。