簡體   English   中英

單元測試......如何改進它

[英]Unit testing… how to improve it

我想測試一段返回對象的代碼。

我使用NUnit並在測試類中編寫一個方法來測試我的方法是否正常工作...

[Test]
public void GetMyObjectFromLog()
{
     string _xmlFilePath = @"C:\XmlFile.xml";
     MyObjectParser _myObjectParser = new MyObjectParser();
     MyObject _mockMyObject = new MyObject
                              {
                                   Title = "obj",
                                   Name = "objName"
                              }
     MyObject _myObject = _myObjectParser.GetMyObjectFromLog(_xmlFilePath);

     Assert.AreEqual(_mockMyObject , _myObject);
}

此測試不起作用,因為MyObject不會覆蓋Equals方法,並且我不想僅為測試目的而重寫Equals方法。

所以我重寫了這樣的測試:

[Test]
public void GetMyObjectFromLog()
{
     string _xmlFilePath = @"C:\XmlFile.xml";
     MyObjectParser _myObjectParser = new MyObjectParser();
     MyObject _myObject = _myObjectParser.GetMyObjectFromLog(_xmlFilePath);

     Assert.AreEqual("obj", _myObject.Title);
     Assert.AreEqual("objName", _myObject.Name);
}

好吧,它有效......但這個測試是否相關? 而且,對文件有依賴性。

使用模擬框架而不是相關嗎? 以及如何使用它?

謝謝 !

首先,解析器內部的方法應該是名稱“Parse”而不是“Get”。

其次,如果你不希望對象本身能夠將自己與另一個對象進行比較,那么就像你所做的那樣比較它們(屬性屬性)就完全沒問題了。 但是這可以在測試類中提取到輔助方法中。

最后,您並不想將解析器與文件緊密耦合。 你只想解析文本。 如果要包含一個靜態幫助器方法,該方法也會打開一個文件和所有內容,這是您的選擇,但它不應該是純實例依賴項。

[Test]
public void ParsesObjectFromXml()
{
     string xmlInput = " ... ";
     MyObjectXmlParser parser = new MyObjectXmlParser();
     MyObject expected = new MyObject() {Title = "obj", Name="objName"};

     AssertMyObjectsAreEqual(expected, parser.Parse(xmlInput));
}

private bool AssertMyObjectsAreEqual(MyObject expected, MyObject actual)
{
     Assert.AreEqual(expected.Title, actual.Title);
     Assert.AreEqual(expected.Name, actual.Name);
}

現在你的班級和考試都更清晰,只有一個責任。

關於對文件的依賴(甚至看起來不在項目中!):

您可以覆蓋_myObjectParser.GetMyObjectFromLog以接受Stream。 然后,您可以將該XML文件添加為嵌入式資源,並從程序集中讀取它。

絕對可以有一個文件的引用。 通常有兩種測試類型:單元測試和集成測試。

集成測試總是與某些文件/數據庫或其他任何東西進行交互。 在您的情況下,您可以通過模擬_myObjectParser.GetMyObjectFromLog來改進測試。

您可以自己編寫模擬或使用像rhinomocks這樣的框架。 nunit / rhinomocks的一本非常好的書是:單元測試的藝術。

一個更好的可測試版本的GetMyObjectFromLog可能如下所示:

public MyObject GetMyObjectFromLog(IMyXmlReader reader)
{
    var xmlData = reader.GetData();
    //make your object here
    var obj = new MyObject(xmlData);
    return obj;  
}

然后,您可以實現2個實現接口IMyXmlReader的新類,一個從生成代碼的文件中讀取的類,以及一個在GetData()上始終返回相同字符串的類。

然后,您可以使用您的類,它始終返回單元測試的靜態字符串。

了解? 對不起我的英語不好 :)

是的,它看起來不錯。 但是,如果在主項目中不需要它,則可以在測試項目中覆蓋Equals 例如,通常我創建的類將私有和受保護的類提升為公共類。 因此,您可以自由擴展主項目,以便在測試項目中進行簡單測試。

文件依賴是可以的,只需將此文件放在測試套件項目中即可。

單元測試的目的是測試代碼的邏輯,上面的測試是做兩件事:1。邏輯2.搜索

我說搜索是因為你試圖匹配你在外部文件中創建的對象。 如果你這樣做,問題是如果沒有外部文件並且你不想要它,你的構建將開始中斷。

解決方案:隨時創建文件,但不創建物理文件,在內存中創建文件,然后插入需要匹配的對象,然后匹配該對象。

這樣這個測試永遠不會破壞。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM