2008-09-09 7 views
8

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

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

ответ

6

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

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

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

+0

ОТД должны быть локально сохранены, так что тестовый модуль не зависит от сетевых услуг будут доступны. –

6

Раньше я использовал XmlUnit и нашел, что это полезно.

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

+0

Спасибо за ссылку XmlUnit, звучит интересно и полезно – Vin

0

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

Вы можете использовать DTD для проверки достоверности сгенерированного xml, который я бы просто прочитал так, как вы делаете в своей программе. Я лично не буду включать его inline (как String); всегда существует зависимость между вашим кодом приложения и модульным тестом. Когда сгенерированный 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);