C# 如何对xml文件进行单元测试?
我已经为下面的xml文件准备了一个XSD模式C# 如何对xml文件进行单元测试?,c#,xml,unit-testing,C#,Xml,Unit Testing,我已经为下面的xml文件准备了一个XSD模式 <?xml version="1.0"?> <note> <to> </to> <from> </from> <datetime> </datetime> <heading> </heading> <body> </body> </note> 我实现了一个记事本生成器来根据模式生
<?xml version="1.0"?>
<note>
<to> </to>
<from> </from>
<datetime> </datetime>
<heading> </heading>
<body> </body>
</note>
我实现了一个记事本生成器来根据模式生成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>
百合花
露西
--日期--时间--
回复
没问题
,其中,
是生成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;
// ...
现在在单元测试中,您可以使用您选择的隔离框架来伪造依赖关系,并根据您自己设置的确定性值执行断言(示例):
您的XSD架构不是XSD架构。请参见有关架构外观的详细信息。它应该以
开头。是的,它不是架构。我的意思是,我有一个xml文件的模式。您到底想单元测试什么?我想测试生成的xml文件是否根据给定的模板正确,例如我上面给出的两个模板。@user3118189请区分根据模板的正确性和根据模式的正确性。如果插入粗体标题
作为标题,会发生什么情况?它看起来仍然是一个有效的标题,但可能会破坏您的模式。使用此方法,您可以在不准备xml文件的情况下测试多少用例(以及容易出错的任务)?
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));