Compare scala.xml.Elem object in unit test

前端 未结 4 1887
执笔经年
执笔经年 2021-02-19 06:21

I have two scala.xml.Elem objects (actual, expected). I am using JUnit 4, but have also included XMLUnit 1.3.

Is there any easy way to compare the two objec

4条回答
  •  感动是毒
    2021-02-19 07:00

    I modified @Nick's code to work with JDom2. In his code, because of how zip works, if expectedXML has trailing elements that are not in actualXML, the test passes. I fixed that bug, and made the comparison of trailing elements optional:

    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)
      }
    }
    

    I wrote this trait to mix into the test code:

    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)
      }
    }
    

    I invoked the test this way:

    class XmlTest extends WordSpec with MustMatchers {
      // test code here
      assertEqual(actualXML.getRootElement, expectedXML.getRootElement, ignoreTrailingElements=true)
    }
    

提交回复
热议问题