<p>I have a class with a <code>ToString</code> method that produces XML. I want to unit test it to ensure it is producing valid xml. I have a DTD to validate the XML against. </p>

<p><strong>Should I include the DTD as a string within the unit test to avoid a dependency</strong> on it, or is there a smarter way to do this?</p>

[{'answer_id': 51780, 'author': 'Eli Courtwright', 'author_id': 1694, 'author_profile': 'https://Stackoverflow.com/users/1694', 'pm_score': 4, 'selected': True, 'text': "<p>If your program validates the XML against the DTD during normal execution, then you should just get the DTD from wherever your program will get it.</p>\n\n<p>If not and the DTD is extremely short (only a few lines), then storing it as a string in your code is probably okay.</p>\n\n<p>Otherwise, I'd put it in an external file and have your unit test read it from that file.</p>\n"}, {'answer_id': 51842, 'author': 'Wheelie', 'author_id': 1131, 'author_profile': 'https://Stackoverflow.com/users/1131', 'pm_score': 3, 'selected': False, 'text': '<p>I\'ve used <a href="http://xmlunit.sourceforge.net/" rel="nofollow noreferrer">XmlUnit</a> in the past and found it to be useful.</p>\n\n<p>It can be used to validate XML against a schema or compare your XML against a string. It is clever enough to understand XML\'s parsing rules.\nFor example it knows that "&lt;e1/&gt;" is equivalent to "&lt;e1&gt;&lt;/e1&gt;" and can be configured to ignore or include whitespace.</p>\n'}, {'answer_id': 30647084, 'author': 'R. Oosterholt', 'author_id': 1183010, 'author_profile': 'https://Stackoverflow.com/users/1183010', 'pm_score': 0, 'selected': False, 'text': '<p>Using a DTD in the unit test to test its validity is one thing, testing for the correct content is another.</p>\n\n<p>You can use the DTD to check for the validity of the generated xml which I would simply read the way you do in your program. I personally would not include it inline (as a String); there is always a dependency between you application code and the unit test. When the generated xml changes, the DTD will also change.</p>\n\n<p>To test for the correct content I would go for <a href="http://www.xmlunit.org" rel="nofollow">XMLUnit</a>. </p>\n\n<p>Asserting xml using XMLUnit:</p>\n\n<pre><code>XMLUnit.setIgnoreWhitespace(true);\nXMLUnit.setIgnoreDiffBetweenTextAndCDATA(true);\n\nDiff diff = new Diff(expectedDocument, obtainedDocument);\nXMLAssert.assertXMLIdentical("xml invalid", diff, true);\n</code></pre>\n\n<p>One thing you might come across is the fact that the generated xml might contain changing identifiers (id/uid attributes or alike). This can be solved by using a <a href="http://www.xmlunit.org/api/java/master/org/custommonkey/xmlunit/DifferenceListener.html" rel="nofollow">DifferenceListener</a> when asserting the generated xml.</p>\n\n<p>Example implementation of such DifferenceListener:</p>\n\n<pre><code>public class IgnoreVariableAttributesDifferenceListener implements DifferenceListener {\n\n    private final List&lt;String&gt; IGNORE_ATTRS;\n    private final boolean ignoreAttributeOrder;\n\n    public IgnoreVariableAttributesDifferenceListener(List&lt;String&gt; attributesToIgnore, boolean ignoreAttributeOrder) {\n        this.IGNORE_ATTRS = attributesToIgnore;\n        this.ignoreAttributeOrder = ignoreAttributeOrder;\n    }\n\n    @Override\n    public int differenceFound(Difference difference) {\n        // for attribute value differences, check for ignored attributes\n        if (difference.getId() == DifferenceConstants.ATTR_VALUE_ID) {\n            if (IGNORE_ATTRS.contains(difference.getControlNodeDetail().getNode().getNodeName())) {\n                return RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL;\n            }\n        }\n        // attribute order mismatch (optionally ignored)\n        else if (difference.getId() == DifferenceConstants.ATTR_SEQUENCE_ID &amp;&amp; ignoreAttributeOrder) {\n            return RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL;\n        }\n        // attribute missing / not expected\n        else if (difference.getId() == DifferenceConstants.ATTR_NAME_NOT_FOUND_ID) {\n            if (IGNORE_ATTRS.contains(difference.getTestNodeDetail().getValue())) {\n                return RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL;\n            }\n        }\n\n        return RETURN_ACCEPT_DIFFERENCE;\n    }\n\n    @Override\n    public void skippedComparison(Node control, Node test) {\n        // nothing to do\n    }\n}\n</code></pre>\n\n<p>using DifferenceListener:</p>\n\n<pre><code>    XMLUnit.setIgnoreWhitespace(true);\n    XMLUnit.setIgnoreDiffBetweenTextAndCDATA(true);\n\n    Diff diff = new Diff(expectedDocument, obtainedDocument);\n    diff.overrideDifferenceListener(new IgnoreVariableAttributesDifferenceListener(Arrays.asList("id", "uid"), true));\n\n    XMLAssert.assertXMLIdentical("xml invalid", diff, true);\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/51771', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/1736/']