2017-02-21 34 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测试正在工作。

相关问题