Я изменил код @ Ника для работы с JDom2 . В его коде из-за того, как работает zip
, если expectedXML
имеет конечные элементы, которых нет в actualXML
, тест проходит. Я исправил эту ошибку и сделал необязательным сравнение конечных элементов:
trait XMLTest extends XMLSupport {
/** Verify that the XMLs are the same, regardless of attribute or element ordering and ignoring whitespace. */
def assertEqual(actual: Element, expected: Element, ignoreTrailingElements: Boolean=false): Assertion = {
// depth-first comparison
def recurse(actual: Element, expected: Element): Assertion = {
import scala.collection.JavaConverters._
val actualChildren: Seq[Element] = actual.getChildren.asScala.sortBy(_.getName)
val expectedChildren: Seq[Element] = expected.getChildren.asScala.sortBy(_.getName)
(actualChildren zip expectedChildren) foreach { case (actualChild, expectedChild) =>
recurse(actualChild, expectedChild)
}
actual.getName shouldEqual expected.getName
actual.getTextNormalize shouldEqual expected.getTextNormalize
actual.getAttributes.asScala.map(_.toString).sorted shouldEqual expected.getAttributes.asScala.map(_.toString).sorted
if (!ignoreTrailingElements && actualChildren.size < expectedChildren.size) {
val diff = expectedChildren.drop(actualChildren.size)
fail("Extra XML children found: " + prettyPrint(diff))
} else succeed
}
recurse(actual, expected)
}
}
Я написал эту черту для смешивания с тестовым кодом:
trait XMLSupport {
import org.jdom2.output.{Format, XMLOutputter}
def prettyPrint(doc: Document): String = {
val xmlOutput = new XMLOutputter()
xmlOutput.setFormat(Format.getPrettyFormat)
xmlOutput.outputString(doc)
}
def prettyPrint(elements: Seq[Element]): String = {
import scala.collection.JavaConverters._
val xmlOutput = new XMLOutputter()
xmlOutput.setFormat(Format.getPrettyFormat)
xmlOutput.outputString(elements.asJava)
}
}
Я вызвал тест следующим образом:
class XmlTest extends WordSpec with MustMatchers {
// test code here
assertEqual(actualXML.getRootElement, expectedXML.getRootElement, ignoreTrailingElements=true)
}