2017-02-21 1 views
0

Ich habe eine Reihe von Komponententests, die eine gespeicherte XML-Datei in JAXB-Objekte entpacken. Sie arbeiteten. Diese Tests verwendeten PowerMock (1.6.6) aufgrund eines Details in der CUT (zu testender Code), für die eine Klausel "whenNew" erforderlich war.JAXB beschwert sich darüber, dass ein Namespace vorhanden ist, wenn er da sein sollte

Ich entschied mich für eine abstrakte Version hinter einer Objektfabrik, die es mir erlaubte, zu reinem Mockito zu wechseln.

Als ich das tat, bekam ich unerklärliche Probleme beim Entpacken von XML-Dateien in JAXB-Objekte während des Tests. Es hat einfach nicht bestimmte Elemente in den JAXB-Objekten gespeichert.

Die Methode, die die unmarshalling tut sieht wie folgt aus:

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

habe ich es auf die folgende Informationen zu bekommen:

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

Was ich fand, war, dass der unmarshalling Prozess weigere Speichern Sie einige Elemente in den JAXB-Instanzen, da XML-Schemafehler aufgetreten sind.

Zum Beispiel sah ich nach der Änderung dieses Codes Nachrichten wie folgt. Ich beziehe mich hier auf den Namespace "http://namespace1.xsd", der offensichtlich nicht sein ursprünglicher Name war, aber alle Orte, wo dieser spezifische Namespace in diesen Beispielen gezeigt wird, verwende ich diesen "namespace1.xsd" Namen.

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

Wie Sie sehen können, erklärte das XML-Dokument, dass das Element in einem Namensraum, sondern die „{}“ scheint zu implizieren, dass kein Namespace erwartet wurde.

Dies ist ein Auszug aus der JAXB-Klasse generiert:

@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; 

Und hier ist die @XmlSchema Anmerkung aus dem "Paket-info" erzeugt aus dem gleichen Paket:

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

So, Nachdem ich diesen Fehler bekommen hatte, entschied ich mich zu versuchen, einen "das könnte nicht funktionieren" zu ändern.

änderte ich die XML-Datei, so dass dieser die analoge Auszug ist:

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

Die einzige Änderung, die ich die Namespacepräfix für „namespace1.xsd“ gemacht wurde. Es scheiterte mit "" (leer), was richtig ist, soweit ich sehen kann. Ich habe es in "ns1" geändert, aber nur in der Deklaration. Ich verweise eindeutig nicht auf dieses Präfix im Körper des Elements. Dies macht den Test PASS.

Bitte stellen Sie meine Gesundheit wieder her.

Antwort

0

Das Problem endete damit, dass die XML-Dokumente, die die Tests verwendeten, tatsächlich nicht Schema-gültig waren. Sie hatten subtile Probleme, die dazu führten, dass die Validierung fehlschlug, aber diese Probleme wurden dort von anderen Entwicklern bewusst platziert, weil sie feststellten, dass die PowerMock-Tests nicht bestanden würden, ohne dass diese FEHLER vorhanden waren. Ich versuche immer noch herauszufinden, warum PowerMock nur mit den Dateien in diesem Zustand arbeiten würde, aber meine Dokumente sind jetzt Schema-gültig, und die Mockito-Tests funktionieren.

Verwandte Themen