![](/img/trans.png)
[英]How Can I Improve this Translator Object Factory to simplify unit testing?
[英]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.