Лучший способ проверить XML в модульном тесте? - PullRequest
9 голосов
/ 09 сентября 2008

У меня есть класс с ToString методом, который производит XML. Я хочу провести его модульное тестирование, чтобы убедиться, что оно производит действительный xml. У меня есть DTD для проверки XML.

Стоит ли включать DTD в качестве строки в модульном тесте, чтобы избежать зависимости от него, или есть более разумный способ сделать это?

Ответы [ 3 ]

6 голосов
/ 09 сентября 2008

Я использовал XmlUnit в прошлом и нашел его полезным.

Может использоваться для проверки XML по схеме или сравнения вашего XML со строкой. Он достаточно умен, чтобы понять правила синтаксического анализа XML. Например, он знает, что «» эквивалентно « </ e1>» и может быть настроен на игнорирование или включение пробела.

6 голосов
/ 09 сентября 2008

Если ваша программа проверяет XML на соответствие DTD во время обычного выполнения, то вы должны просто получить DTD, откуда ваша программа получит его.

Если нет, и DTD очень короткий (всего несколько строк), то, вероятно, все в порядке в виде строки в вашем коде.

В противном случае я бы поместил его во внешний файл, и ваш тестовый модуль считал его из этого файла.

0 голосов
/ 04 июня 2015

Использование DTD в модульном тесте для проверки его достоверности - это одно, а проверка правильности содержимого - другое.

Вы можете использовать DTD для проверки правильности сгенерированного XML, который я просто прочитал бы так, как вы делаете в своей программе. Я лично не включил бы это в строку (как строка); всегда есть зависимость между кодом приложения и модульным тестом. Когда сгенерированный XML изменяется, DTD также изменится.

Чтобы проверить правильность содержимого, я бы выбрал XMLUnit .

Утверждение xml с использованием XMLUnit:

XMLUnit.setIgnoreWhitespace(true);
XMLUnit.setIgnoreDiffBetweenTextAndCDATA(true);

Diff diff = new Diff(expectedDocument, obtainedDocument);
XMLAssert.assertXMLIdentical("xml invalid", diff, true);

Одна вещь, с которой вы можете столкнуться, это тот факт, что сгенерированный xml может содержать изменяющиеся идентификаторы (атрибуты id / uid или подобные). Эту проблему можно решить с помощью DifferenceListener при подтверждении созданного XML.

Пример реализации такого DifferenceListener:

public class IgnoreVariableAttributesDifferenceListener implements DifferenceListener {

    private final List<String> IGNORE_ATTRS;
    private final boolean ignoreAttributeOrder;

    public IgnoreVariableAttributesDifferenceListener(List<String> attributesToIgnore, boolean ignoreAttributeOrder) {
        this.IGNORE_ATTRS = attributesToIgnore;
        this.ignoreAttributeOrder = ignoreAttributeOrder;
    }

    @Override
    public int differenceFound(Difference difference) {
        // for attribute value differences, check for ignored attributes
        if (difference.getId() == DifferenceConstants.ATTR_VALUE_ID) {
            if (IGNORE_ATTRS.contains(difference.getControlNodeDetail().getNode().getNodeName())) {
                return RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL;
            }
        }
        // attribute order mismatch (optionally ignored)
        else if (difference.getId() == DifferenceConstants.ATTR_SEQUENCE_ID && ignoreAttributeOrder) {
            return RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL;
        }
        // attribute missing / not expected
        else if (difference.getId() == DifferenceConstants.ATTR_NAME_NOT_FOUND_ID) {
            if (IGNORE_ATTRS.contains(difference.getTestNodeDetail().getValue())) {
                return RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL;
            }
        }

        return RETURN_ACCEPT_DIFFERENCE;
    }

    @Override
    public void skippedComparison(Node control, Node test) {
        // nothing to do
    }
}

с использованием DifferenceListener:

    XMLUnit.setIgnoreWhitespace(true);
    XMLUnit.setIgnoreDiffBetweenTextAndCDATA(true);

    Diff diff = new Diff(expectedDocument, obtainedDocument);
    diff.overrideDifferenceListener(new IgnoreVariableAttributesDifferenceListener(Arrays.asList("id", "uid"), true));

    XMLAssert.assertXMLIdentical("xml invalid", diff, true);
...