質問

私はクラスを持っています ToString XML を生成するメソッド。単体テストを行って、有効な XML が生成されていることを確認したいと考えています。XML を検証するための DTD があります。

依存関係を避けるために単体テスト内に DTD を文字列として含めるべきか それとももっと賢い方法はあるのでしょうか?

役に立ちましたか?

解決

プログラムが通常の実行中に XML を DTD と照合して検証する場合は、プログラムが取得できる場所から DTD を取得する必要があります。

そうでなく、DTD が非常に短い (数行のみ) 場合は、コード内に文字列として保存してもおそらく問題ありません。

それ以外の場合は、それを外部ファイルに置き、単体テストでそのファイルから読み取るようにします。

他のヒント

使ったことがある XmlUnit 過去に使ってみて、便利だと感じました。

これは、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
    }
}

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);
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top