簡體   English   中英

如何對xml文件進行單元測試?

[英]How to unit test an xml file?

我已經為以下xml文件提供了XSD架構

<?xml version="1.0"?>
<note>
 <to> </to>
 <from> </from>
 <datetime>  </datetime>
 <heading> </heading>
 <body> </body>
</note>

我實現了一個NoteGnerator來根據模式生成xml文件。 必須針對某些模板/規范生成xml文件,例如:

<?xml version="1.0"?>
<note>
 <to> Lucy </to>
 <from> Lily </from>
 <datetime> --date--time-- </datetime>
 <heading> reminder </heading>
 <body> do not forget my pen </body>
</note>

另一個模板/規范如下:

<?xml version="1.0"?>
<note>
 <to> Lily </to>
 <from> Lucy </from>
 <datetime> --date--time-- </datetime>
 <heading> reply </heading>
 <body> no problem </body>
</note>

,其中<datetime>是生成xml時的動態值(因此無法預先確定此值)。 基於XSD方案和這兩個XML規范,我可以輕松生成XML消息。

如何對生成的XML文件進行單元測試?

我是否需要再次驗證生成的XML文件? 或者我需要使用一些diff工具來比較生成的xml文件和模板? 因為日期時間是動態的,所以每次生成xml文件時它都不同,那么如何將它們與模板進行比較呢? 或者我需要將xml反序列化為c#對象,然后測試c#對象?

這可能對你有所幫助。 在這里,我創建一個對象,分配值,將其寫入XML,讀取XML,並將其與原始對象進行比較。 我假設你有全班結構。

// This is your expected object which you are going to write to xml.
var sourceObject = new SomeClassToWriteInXML();

// Writing object to XML.
var document = new XDocument();
var serializer = new XMLSerializer(typeof(SomeClassToWriteInXML));
using (var writer = document .CreateWriter())
{
    serializer.Serialize(writer, source);
}
// write document to a file.

// Now document has the XML document.
// Need to read file you have just created. For testing sake I am reading document.
var actual = new SomeClassToWriteInXML();
// Deserialize xml to get actual object (which should be equal to sourceObject)
using (var reader = document.CreateReader())
{
    actual = (SomeClassToWriteInXML)serializer.Deserialize(reader);
}

Assert.AreEqual(expected.First(), actual.First());

您可以輕松地比較生成的XML節點值,但datetime除外。 這是因為它具有非確定性。 在單元測試(和代碼設計)中,這些問題通常以兩種方式解決:

  • 完全消除非決定論
  • 放松與非確定性相關的要求(例如,通過不執行精確匹配,而是某種模糊/近似)

使用第一個解決方案,您的筆記生成組件需要將當前日期時間抽象為外部服務/依賴項,例如:

public class NoteGenerator
{
    private readonly ICurrentDateProvider currentDateProvider;
    public NoteGenerator(ICurrentDateProvider )currentDateProvider
    {
        this.currentDateProvider = currentDateProvider;
    }

    public string GenerateNote()
    {
        var currentDate = currentDateProvider.Now;
        // ...

現在在單元測試中,您可以使用您選擇的隔離框架偽造該依賴關系,並對您自己設置的確定性值執行斷言(例如使用FakeItEasy ):

var dateProvider = A.Fake<ICurrentDateProvider>();
A.CallTo(() => dateProvider.Now).Returns(new DateTime(2014, 01, 31, 10, 30));
var generator = new NoteGenerator(dateProvider);

// ...

第二種方法是替換日期時間必須是這個值 -匹配日期時間不得早於 -匹配,例如:

var oneMinuteAgo = DateTime.Now.AddMinutes(-1.0);
var generator = new NoteGenerator();

var dateFromXml = // extract 
Assert.That(dateFromXml, Is.GreaterThan(oneMinuteAgo));

暫無
暫無

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

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