简体   繁体   English

如何对xml文件进行单元测试?

[英]How to unit test an xml file?

I have an XSD schema already for the following xml file 我已经为以下xml文件提供了XSD架构

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

I implemented a NoteGnerator to generate xml files based on the schema. 我实现了一个NoteGnerator来根据模式生成xml文件。 The xml files must have to generated regarding some templates/specifications, such as: 必须针对某些模板/规范生成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>

Another template/specification would be like: 另一个模板/规范如下:

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

, where <datetime> is a dynamic value when the xml is generated (so this value cannot be predetermined). ,其中<datetime>是生成xml时的动态值(因此无法预先确定此值)。 Based on the XSD scheme and these two XML specifications, I can easily generate XML messages. 基于XSD方案和这两个XML规范,我可以轻松生成XML消息。

How can I unit test the generated XML files? 如何对生成的XML文件进行单元测试?

Do I need to validate the generated XML files again the schema? 我是否需要再次验证生成的XML文件? Or I need to use some diff tool to compare the generated xml files and the template? 或者我需要使用一些diff工具来比较生成的xml文件和模板? Because the datetime is dynamic, it is different each time when an xml file is generated, so how to compare them with the template? 因为日期时间是动态的,所以每次生成xml文件时它都不同,那么如何将它们与模板进行比较呢? Or I need to deserialise xml to c# object and then test the c# object ? 或者我需要将xml反序列化为c#对象,然后测试c#对象?

This might be helpful for you. 这可能对你有所帮助。 In this I am creating a object, assigning values, writing it to XML, reading the XML, and comparing it to original object. 在这里,我创建一个对象,分配值,将其写入XML,读取XML,并将其与原始对象进行比较。 I am assuming that you have whole class structure. 我假设你有全班结构。

// 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());

You can easily compare generated XML node values, except from the datetime . 您可以轻松地比较生成的XML节点值,但datetime除外。 This is because of its non-deterministic nature. 这是因为它具有非确定性。 In unit testing (and code design) such problems are usually solved in either of two ways: 在单元测试(和代码设计)中,这些问题通常以两种方式解决:

  • removing non-determinism altogether 完全消除非决定论
  • loosening your requirements relating to non-determinism (eg. by not performing exact matching but rather some sort of fuzzy/approximated one) 放松与非确定性相关的要求(例如,通过不执行精确匹配,而是某种模糊/近似)

With first solution, your note generating component would need to abstract out current date time to external service/dependency, say: 使用第一个解决方案,您的笔记生成组件需要将当前日期时间抽象为外部服务/依赖项,例如:

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

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

Now in unit test you can fake that dependency using your isolation framework of choice and perform assertions against deterministic value you set yourself (example with FakeItEasy ): 现在在单元测试中,您可以使用您选择的隔离框架伪造该依赖关系,并对您自己设置的确定性值执行断言(例如使用FakeItEasy ):

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

// ...

The second approach is to replace the date time must be this value -matching with date time must not be older than -matching, for example: 第二种方法是替换日期时间必须是这个值 -匹配日期时间不得早于 -匹配,例如:

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