我有一堂课,有一个 ToString 生成 XML 的方法。我想对其进行单元测试以确保它生成有效的 xml。我有一个 DTD 来验证 XML。

我是否应该将 DTD 作为字符串包含在单元测试中以避免依赖性 或者有更聪明的方法来做到这一点?

有帮助吗?

解决方案

如果您的程序在正常执行期间根据 DTD 验证 XML,那么您应该从程序将获取 DTD 的任何地方获取它。

如果不是,并且 DTD 非常短(只有几行),那么将其作为字符串存储在代码中可能就可以了。

否则,我会将其放入外部文件中,并让您的单元测试从该文件中读取它。

其他提示

我用过 Xml单元 过去发现它很有用。

它可用于根据模式验证 XML 或将 XML 与字符串进行比较。它足够聪明,能够理解XML的解析规则。例如,它知道“<e1/>”相当于“<e1></e1>”,并且可以配置为忽略或包含空格。

在单元测试中使用 DTD 来测试其有效性是一回事,测试内容的正确性又是另一回事。

您可以使用 DTD 来检查生成的 xml 的有效性,我将按照您在程序中的方式简单地读取它。我个人不会将其包含在内联(作为字符串);应用程序代码和单元测试之间始终存在依赖关系。当生成的xml发生变化时,DTD也会发生变化。

为了测试正确的内容,我会去 XML单元.

使用 XMLUnit 断言 xml:

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

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

您可能会遇到的一件事是,生成的 xml 可能包含不断变化的标识符(id/uid 属性或类似属性)。这可以通过使用来解决 差异监听器 当断言生成的 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
    }
}

使用差异监听器:

    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);
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top