2017-08-09 56 views
0

我試着寫一些JUnit測試的Docx4J發生器我已經寫。 我想我發生器的輸出節點與我想從字符串加載預期節點進行比較。Doc4j:比較兩個文件失敗,因爲不同的元素類型

所以,我創建了我的「實際」節點(發電機輸出),像這樣:

Node xmlNodeActual = XmlUtils.marshaltoW3CDomDocument(actual).getDocumentElement(); 

其中,「實際」是由我的發電機創建的對象。

對於我的「預期」節點,我寫了下面的代碼:

Document doc = docBuilder.parse(new InputSource(new ByteArrayInputStream(strXmlNode.getBytes("utf-8")))): 
Node xmlNodeExpected = doc.getDocumentElement(); 

strXmlNode是抱着期望的XML字符串。 雖然我的兩個節點都是平等的,據我可以從視覺差異來講,調用下面的產量「假」的結果:

xmlNodeActual.isEqualNode(xmlNodeExpected) 

我懷疑的原因是運行時類型的兩個節點的不同:

  • xmlNodeActual:org.apache.xerces.dom.DeferredElementImpl
  • xmlNodeExpected:org.apache.xerces.dom.ElementNSImpl

我喜歡我的測試設計,因爲它可以讓我爲大型生成器快速編寫大量測試用例。但是,我沒有看到將這種方法與「isEqualNode」結合使用的方法。 我必須寫我自己的比較器或者是有辦法,我不知道,以確保類型節點都是一樣的嗎?用這樣的方法

回答

0

注意@邁克爾凱和@JasonPlutext貢獻有趣和更好的選擇上一般情況下如何測試XML輸出,您可能需要考慮。

至於我的具體問題和問題,即比較兩個XML節點與「isEqualNode」,一個源於輸入字符串,一個源於數據轉換,我不得不做下列事情:而不是解析字符串,我可以通過InputStream解組,從而獲得所需的節點類型。

// creating the "actual" node I want to test (nothing changed here) 
Node xmlNodeActual = XmlUtils.marshaltoW3CDomDocument(actual).getDocumentElement(); 

//... 

// Instead of parsing the string, just unmarshal and marshal it once 
Object expected = XmlUtils.unmarshal(new ByteArrayInputStream(strXmlNode.getBytes("utf-8"))); 
Node xmlNodeExpected = XmlUtils.marshaltoW3CDomDocument(expected).getDocumentElement(); 
if(!xmlNodeActual.isEqualNode(xmlNodeExpected)) { 
// ... 
} 

這產生了相同的節點類型,並按我的設置工作。儘管如此,比較兩種XML樹的方式有一些缺陷,正如Michael Kay所指出的那樣,所以不要認爲這是最佳做法,而是要求通用的XML比較的另一個答案。

0

的一個問題是,它只是給出了一個布爾答案,它不會告訴你什麼是兩個節點之間的實際差異。另一個問題是,你不能告訴它你認爲什麼差異是顯着的:例如(據我所知)冗餘名稱空間聲明被認爲是重要的這種特定的方法。空白通常是有問題的。我不得不使用XPath深等於()方法同樣的問題,並寫下了saxon:deep-equal變異的結果。但我現在更願意使用一組XPath斷言來測試預期的結果。 W3C的XSLT測試套件使用與測試斷言像這樣的這種技術:

<result> 
    <all-of> 
     <assert>/root/p[1]/text()[1] = 'Tekst '</assert> 
     <assert>/root/p[1]/text()[2] = ' etc..'</assert> 
     <assert>/root/p[2]/text()[1] = 'Tekst '</assert> 
     <assert>/root/p[2]/text()[2] = ' etc..'</assert> 
    </all-of> 
    </result> 

我沒有在同一時間有一個小工具,它會生成一個XML文檔的斷言這樣的名單,但我現在傾向於做他們手動。最大的好處是,如果出現問題,診斷程序會告訴你哪個斷言失敗。

+0

感謝邁克爾,我意識到我的方法的侷限性。但考慮到我正在工作的技術和非功能限制,這將是一個很好的妥協。我比較的節點很小,但很多。在我的設置中,冗餘名稱空間依賴項和空白都沒有問題,但是感謝您指出它。我寫過類似於saxon的東西:對於不同於XML的語言,深入等同於之前,但是我的問題與我的方法相比較少,如果有一種簡單的方法來控制分析產生的節點類型。 –

+0

該規範沒有提示基於第二個節點樹的實現類允許比較失敗,但當然在實現中可能存在一個錯誤。就我個人而言,我認爲您忽略的兩棵樹之間存在較小的差異的可能性更大。可能值得下載Saxon並查看fn:deep-equal()(或者saxon:deep-equal())所說的內容。 –

+0

我想我在這裏不同意: 請查看[doc](https://docs.oracle.com/javase/7/docs/api/org/w3c/dom/Node.html#isEqualNode)。 它讀取: _兩個節點是相等的當且僅當滿足以下條件:_ _這兩個節點是相同類型._ _..._ –

0
+0

嗨@JasonPlutext。感謝提示。那些,伴隨着一個愉快的睡眠之夜,讓我得到了我所尋找的實用解決方案(將盡快更新我的問題,並且現在我已經結束了)。一般來說,我認爲xmlunit是正確的選擇。 請注意:我的聲望還不夠高,無法顯示我對此答案的滿意度。 –

相關問題