XMLSerializer在TeamCity上产生不同的结果

问题描述 投票:1回答:3

我们已经为TeamCity添加了旧版解决方案。尽管其中一个单元测试在本地通过,但现在它还是失败了。

单元测试检查XmlSerializer的实际输出字符串是否符合预期。

string expectedXmlText = File.ReadAllText("TestFile.xml");
objectToSerialize = ...;

string actual = UtilsClass.SerializeObject(objectToSerialize);

Assert.That(xmlText, Is.EqualTo(expectedXmlText));

在TeamCity中,它失败并显示以下消息:

Test(s) failed.   String lengths are both 476. Strings differ at index 59.
  Expected: "..."utf-16"?>\r\n<Envelope xmlns:xsi="http://www.w3.org/2001/XM..."
  But was:  "..."utf-16"?>\r\n<Envelope xmlns:xsd="http://www.w3.org/2001/XM..."

请注意,命名空间不同,一个以xsi开头,另一个以xsd开头。

现在,我意识到XML在两种情况下都是有效的,并且adn表示同一件事。我还意识到,您不应该编写依赖于XML中名称空间顺序的代码。

问题

  1. 测试XMLSerializer输出的正确方法是检查输出文本是否错误?
  2. 为什么XMLSerializer以不同的顺序返回名称空间?
c# unit-testing teamcity xml-namespaces xmlserializer
3个回答
1
投票

2。

来自Inconsistent Namespace Order using XmlSerializer on x86/x64

名称空间集合在内部只是一个字典。它返回值的顺序是不确定的,并且理论上每次调用它都可以更改。没有韵律或字典排序的原因。如果需要一致的排序,则必须切换到SortedDictionary和朋友。

更具体地说,XmlSerializerNamespaces在内部使用哈希表,该哈希表根据字典和哈希码中已有的内容来计算将项目放置在何处。 Hashtable实际上根据插入时发生了多少次冲突来定期重建字典。在MSDN信息中记录了该类型。

得出的结论是,即使对于同一实例,也无法保证对字典进行排序,因为字典(在这种情况下为哈希表)可以对项进行重新排序以提高性能。通常,我们希望单个实例甚至在机器之间都能看到一致的行为,但是并不能保证。


1
投票

[有些人实际上建议避免使用string对象,而要使用反序列化中的实际XML对象(无论是LINQ-to-XML的XDocument还是XmlDocument核心库的System.Xml)。

还有一个问题提出了来自Fluent Assertions的功能,它也显示了一些示例:Unit testing XML Generation


0
投票

我在单元测试中与test_xml nampespaces(XSD和XSI)位置不匹配control_xml命名空间时遇到了相同的问题

解决方案是XMLUnit.NET 2.x,它将XML作为XML对象而不是String进行比较

https://github.com/xmlunit/xmlunit.net

使用Fluent API:

string String_Actual = serializadorAbstract.AsString;
string String_Expected = File.ReadAllText(@"ExpectedOutput\Alumnos.xml");

ISource control = Input.FromString(String_Expected).Build();
ISource test = Input.FromString(String_Actual).Build();

Diff differences = DiffBuilder.Compare(control).WithTest(test).Build();
Assert.IsFalse(differences.HasDifferences());
© www.soinside.com 2019 - 2024. All rights reserved.