2011-04-06 68 views
3

我有一個類,它使用C#中的XmlReader和XmlReaderSettings類來針對模式驗證Xml文件。由於我的應用程序涉及從數據庫讀取Xml數據,因此我決定在MessageBox中向用戶顯示錯誤。因此,任何驗證錯誤以及拋出的任何異常都會顯示在MessageBox中出現的字符串「解析時發生錯誤」。Xml解析器類的單元測試

我也有一個布爾變量,它返回解析是否成功。

現在,我使用Parse函數在Assert中返回的布爾值,同時解析函數解析有效和無效的Xml文件。因此,在運行測試用例套件時,我將這些堆棧的消息框堆積在另一個窗口中。

真正的問題是,當Visual Studio中的單元測試框架告訴我們所有的測試是否通過時,彈出一些這些消息框是可以的。

或者是我只需要返回一個布爾值,然後GUI類顯示相應的錯誤消息的情況。 Q2302。另外,如果我確實需要檢查一個特定的字符串是否被正確解析並存儲到一個數組中,我可以繼承這個主類來添加一些可以幫助我更好地編寫單元測試的功能嗎?

我真的很感謝一些關於我的設計和單元測試應該如何的建議。

另外,我承認在編寫單元測試後,我寫了一個很大的錯誤,之後我寫下了需要測試的類,我知道它應該是相反的。

回答

6

Xml的解析和錯誤消息的顯示是單獨的問題,所以解析器不應該有關於如何顯示錯誤消息的任何知識。

根據您的需求,有幾個選項:

例外

我經常被生活準則:「如果一個方法不能做的工作,拋出一個異常」。如果您需要停止第一個錯誤,那麼例外就是要走的路。

從單元測試的角度來看,如果您傳遞非法數據,請驗證代碼使用[ExpectedException]屬性拋出異常。

[TestMethod, ExpectedException(typeof(ParserValidationException))] 
public void IllegalDataShouldThrowValidationErrors() 
{ 
    var parser = new MyParser(); 
    parser.Parse(dataThatContainsErrors); 
} 

但是,如果您需要忽略非法數據並報告錯誤,則可能需要採用其他方法。

專門返回類型

如果您需要收集所有的錯誤,這是最好的,目的在於保持解析結果和錯誤一起。

public class ParsedResult<T> 
{ 
    public T Result; 
    public List<string> Warnings; 
} 

從單元測試的角度來看,如果您傳遞非法數據,您應該驗證警告列表不是空的。

[TestMethod] 
public void ParsedResultsForIllegalDataShouldContainWarnings() 
{ 
    var parsedResult = new MyParser.Parse<Foo>(dataThatContainsErrors); 

    Assert.IsNotNull(parsedResult); 
    Assert.IsNotNull(parsedResult.Result); 
    Assert.AreEqual(1, parsedResult.Warnings.Count); 
} 

錯誤記者

傳遞一個合作者到對象並將其舉報的調查結果。

public ObjectToReturn Parse(string xml, IProgressReporter progress) 
{ 
    // create xml reader 
    // read values from xml 
    // if a value is invalid, log it 
    progress.AddMessage("property x was invalid. ") 
} 

進度報告可以在你的MessageBox的包裝,或者它可能是一個控制檯輸出,記錄儀等。從單元測試的角度來看,你可以創建一個測試雙捕獲的消息,或者你可以使用模擬框架並驗證它被稱爲一定的次數。這是一個使用Moq的例子。

var mockReporter = new Mock<IProgressReporter>(); 
IProgressReporter reporter = mockReporter.Object; 

var parser = new MyParser(); 
var illegalData = // your illegal data; 

var result = parser.Parse(illegalData, parser); 

Assert.IsNotNull(result, "The value was not parsed correctly."); 
mockReporter.Verify(r => r.AddMessage(It.IsAny<string>()), Times.AtLeast(1)); 
2

我認爲你不應該使用MessageBox來進行錯誤報告,而是將錯誤作爲List<string>傳遞並讓GUI顯示它們。

我喜歡測試驅動的開發,但是在編寫實現後編寫測試也可以。對我來說,寫下更多的努力。