2017-02-21 58 views
0

我有一組單元測試,將存儲的XML文件解組到JAXB對象中。他們在工作。這些測試使用PowerMock(1.6.6),因爲CUT中的一個細節(測試代碼)需要「whenNew」子句。JAXB抱怨應該存在的名稱空間

我決定對一個對象工廠進行抽象,讓我轉向純Mockito。

當我這樣做時,在測試過程中,當將XML文件解組爲JAXB對象時,我開始出現無法解釋的問題。它根本不存儲某些元素到JAXB對象中。

,做解組的方法是這樣的:

protected JAXBElement<?> unmarshallToObject(Node node, Class<?> nodeClassType) throws ServiceException { 
    try { 
     return getUnmarshaller().unmarshal(node, nodeClassType); 
    } catch (JAXBException ex) { 
     baseLogger.error(null, ex, "JAXB Exception while un-marshalling"); 
     throw new ServiceException(UslErrCodes.BACKEND_APP.createServiceErr(BackendConfig.USL.getId(), 
       "JAXB Exception while un-marshalling"), ex); 
    } 
} 

我把它改成下面以獲取更多信息:

protected JAXBElement<?> unmarshallToObject(Node node, Class<?> nodeClassType) throws ServiceException { 
    try { 
     Unmarshaller unmarshaller = getUnmarshaller(); 
     unmarshaller.setEventHandler(new javax.xml.bind.helpers.DefaultValidationEventHandler()); 
     return unmarshaller.unmarshal(node, nodeClassType); 
    } catch (JAXBException ex) { 
     baseLogger.error(null, ex, "JAXB Exception while un-marshalling"); 
     throw new ServiceException(UslErrCodes.BACKEND_APP.createServiceErr(BackendConfig.USL.getId(), 
       "JAXB Exception while un-marshalling"), ex); 
    } 
} 

我發現的是,解組過程被拒絕將某些元素存儲在JAXB實例中,因爲它正在獲取xml架構錯誤。

例如,更改此代碼後,我看到如下消息。我在這裏指的是命名空間「http://namespace1.xsd」,這顯然不是它的原始名稱,但是在這些示例中顯示該特定命名空間的所有位置,我使用這個「namespace1.xsd」名稱。

JAXB Exception while un-marshalling:unexpected element (uri:"http://namespace1.xsd", local:"securityFeeRequired"). Expected elements are <{}securityFeeRequired>,<{}proprietarySegmentFlag>,<{}Treatment>,<{}creditScoreMessage>,<{}ServiceEligibility>,<{}warningMessage>,<{}creditScoreResult>,<{}creditBand> 

正如你所看到的,XML文件指出,該元素是一個命名空間,但「{}」似乎意味着沒有命名空間預期。

這是從生成的JAXB類的摘錄:

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "", propOrder = { "creditScoreResult", "creditScoreMessage", "warningMessage", 
     "securityFeeRequired", "treatment", "creditBand", "proprietarySegmentFlag", "serviceEligibility" }) 
public static class FooResult implements Serializable { 
    private static final long serialVersionUID = 1L; 
    protected String creditScoreResult; 
    protected String creditScoreMessage; 
    protected String warningMessage; 
    protected boolean securityFeeRequired; 

這裏是從同一個包生成的「包信息」的@XmlSchema註釋:

@XmlSchema(namespace="http://namespace1.xsd", elementFormDefault=XmlNsForm.QUALIFIED) 

所以,在得到這個錯誤之後,我決定嘗試做一個「這不可能工作」的改變。

我改變了XML文件,這樣,這是類似的摘錄:

<ExecuteFooResponse xmlns:ns1="http://namespace1.xsd" xmlns:ns2="http://namespace2.xsd"> 
     <FooResult> 
      <securityFeeRequired>false</securityFeeRequired> 
      <Treatment><code>A001</code> 
       <message>No additional fee is required at this time</message> 
      </Treatment> 
      <ServiceEligibility> 
       <productCode>BAR</productCode> 
       <serviceEligibilityIndicator>true</serviceEligibilityIndicator> 
      </ServiceEligibility> 
     </FooResult> 
     <Response> 
      <ns2:code>0</ns2:code> 
      <ns2:description>Success</ns2:description> 
     </Response> 
    </ExecuteFooResponse> 

我所做的唯一變化,就是「namespace1.xsd」命名空間前綴。據我所知,這是「(空白)」,這是正確的。我將它更改爲「ns1」,但只在聲明中。我顯然沒有在元素的主體中引用該前綴。這使得測試通過。

請恢復我的理智。

回答

0

問題最終導致測試使用的XML文檔實際上不是模式有效的。他們有微妙的問題導致驗證失敗,但這些問題是由其他開發人員故意設置的,因爲他們發現PowerMock測試不會在沒有這些錯誤的情況下通過。我仍然在試圖弄清楚爲什麼PowerMock只能用於處於該狀態的文件,但我的文檔現在是模式有效的,並且Mockito測試正在工作。

相關問題