Не так давно разрабатывал функционал, формирующий по некоторому алгоритму разнообразный xml.
Логично, что при написании первого же теста возник традиционный вопрос ленивого программиста: как сэкономить себе силы, а читающим тесты нервы и быстро и наглядно представить, что же я хочу получить?
Поэтому придумал такой вот способ:
Пример
dynamic rootTag = new XmlBuilder("Root", _nmsps);
dynamic modelTag = new XmlBuilder("Model", _nmsps);
dynamic elementTag = new XmlBuilder("ElementRef", _nmsps);
dynamic attrTag = new XmlBuilder("ElementAttribute", _nmsps);
XDocument doc =
rootTag(id: Guid.Empty,
model: modelTag(id: model.ObjectId, name: model.Name,
e1: elementTag(id: er.ObjectId, name: elem1.Name,
ea1: attrTag(id: attr1.ObjectId, name: attr1.Name),
ea2: attrTag(id: attr2.ObjectId, name: attr2.Name)),
e2: elementTag(id: er2.ObjectId, name: elem2.Name)));
XmlBuilder — самописный класс, наследующийся от DynamicObject.
Для создания документа он вызывается как метод и преобразует аргументы либо в атрибуты на основании имени параметра — если это аргумент любого типа, кроме XmlBuilder — либо в дочерние элементы (тут имя параметра не важно) — если это XmlBuilder.
При этом каждый XmlBuilder представляет некоторый тэг в результирующем документе.
В тесте сравниваем то, что надо с тем, что получилось, используя несложный компаратор, в итоге этот тест выглядит как-то так:
//формируем входные данные для теста
//...
//формируем документ, которому должен соответствовать результат
dynamic rootTag = new XmlBuilder("Root", _nmsps);
dynamic modelTag = new XmlBuilder("Model", _nmsps);
dynamic elementTag = new XmlBuilder("ElementRef", _nmsps);
dynamic attrTag = new XmlBuilder("ElementAttribute", _nmsps);
XDocument targetDocument =
rootTag(id: Guid.Empty,
model: modelTag(id: model.ObjectId, name: model.Name,
e1: elementTag(id: er.ObjectId, name: elem1.Name,
ea1: attrTag(id: attr1.ObjectId, name: attr1.Name),
ea2: attrTag(id: attr2.ObjectId, name: attr2.Name)),
e2: elementTag(id: er2.ObjectId, name: elem2.Name)));
//выполняем
var resultDocument = TestableMethod();
//проверяем
var _comparer = new XDocComparer();
Assert.IsTrue(_comparer.Equals(targetDocument, resultDocument));
Для простоты пришлось пожертововать ненужными для меня возможностями (декларациями, например).
Ну и компаратор, в силу того, что он есть IEqualityComparer, не показывает что именно не совпадает, а только конечный результат.
Тем не менее, реализация XmlBuilder тут, а реализация XDocComparer — тут, прошу пользоваться, если кому-то это может пригодиться.
Автор: kayan