2017-01-31 32 views
0

Мы добавили устаревшее решение для TeamCity. Один из модульных тестов теперь терпит неудачу, несмотря на то, что он проходит локально.XMLSerializer производит различные результаты на 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 возвращает пространства имен в другом порядке?

ответ

1

2.

От Inconsistent Namespace Order using XmlSerializer on x86/x64

Коллекция имен только словарь внутренне. Порядок, в котором он возвращает значения, не определен и может, теоретически, меняться каждый раз, когда вы его вызываете. Существует нет рифмы или причины для упорядочения словаря. Если вам нужен последовательный заказ, вам нужно переключиться на SortedDictionary и друзей.

Более конкретно XmlSerializerNamespaces внутренне использует Hashtable, который вычисляет, где разместить элемент на основе того, что уже находится в словаре и хэш-коде. Hashtable фактически перестраивает словарь периодически, исходя из того, сколько коллизий происходит при вставке. Это описано в информации MSDN для типа.

Выписка - это то, что у вас нет гарантий относительно заказа на словари даже для одного и того же экземпляра, потому что словарь (или хэш-таблица в этом случае) может изменять порядок элементов для повышения производительности. Обычно мы ожидаем увидеть последовательное поведение для одного экземпляра и даже через машины, но никаких гарантий нет.

0

1.

Некоторые люди рекомендуют избегать использования string объекта на использовании в реальном объекте XML из десериализации (будь то XDocument от LINQ к XML или XmlDocument из библиотеки System.Xml ядра).

Есть хорошая статья, представляющая функции из Fluent Assertions, которая также показывает некоторые примеры: Unit testing XML Generation