Announcement Announcement Module
Collapse
No announcement yet.
Unit Testing XPath Expressions Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Unit Testing XPath Expressions

    Hi guys,
    I wanted to move my Xpath/JDOM codes out of my endpoint and to unit test them.


    Code:
    private XPathExpression<Element> cusIdExpression;
    Code:
    Namespace namespace = Namespace.getNamespace("etc", NAMESPACE_URI);
    XPathFactory xPathFactory = XPathFactory.instance();
    cusIdExpression = xPathFactory.compile("//etc:cusId", Filters.element(), null, namespace);
    Code:
    @PayloadRoot(namespace = NAMESPACE_URI, localPart = "method1Request")
    @ResponsePayload
    @Transactional(readOnly=true)
    public SearchCustomerResponse method1(@RequestPayload Element customerSearchOptions)
    Long cusId = Long.parseLong(cusIdExpression.evaluateFirst(customerSearchOptions).getText());
    However I am having difficulty to understand how I should be constructing the @RequestPayload Element customerSearchOptions to input to the unit test.

    When I logged the to customerSearchOptions the console, I only found the line below logged

    [Element: <ns:method1Request [Namespace: http://www.etc.com/etc/schemas/1/00]/>]
    and the input XML which I was expecting was not there (i.e, the one being sent from SOAP UI)

    Code:
       <soapenv:Body>
          <ns:method1>
             <ns:cusId>?</ns:cusId>
             <ns:locationCriteria>
                <ns:addressLine1>flacq</ns:addressLine1>
                <ns:city>?</ns:city>
                <ns:postCode>?</ns:postCode>
                <ns:isoCountryCode>Mauritius</ns:isoCountryCode>

    If anyone knows how to actually contruct an input which could be used to unit test the XPath Expressions, I would appreciate if you could share it.

    Code:
    public void testCustomerId() {
    		
    		Element customerSearchOptions = new Element("");
    		customerSearchServicePathExpressionParser.getCusId(customerSearchOptions);
    		
    	}
    Also, if there is also a document which is published. Thanks for sharing that as well.

    Regards
    Kris

  • #2
    Alright guys I made some progress, but I still need to understand how to get the parser to interact with the message context.

    The test now looks like

    Code:
    SaajSoapMessageFactory messageFactory = new SaajSoapMessageFactory();
    		messageFactory.setSoapVersion(SoapVersion.SOAP_11);
    		messageFactory.afterPropertiesSet();
    		
    		InputStream inputStream = ClassLoader.getSystemResourceAsStream("findByCusIdRequest.xml");
    
    		WebServiceMessage request = messageFactory.createWebServiceMessage(inputStream);
    		MessageContext messageContext = new DefaultMessageContext(request , messageFactory);
    		
    		Element customerSearchOptions= new Element("findByCustomerIdRequest", "http://etc/schemas/1/00");
    		cusServicePathExpressionParser.getCusId(customerSearchOptions);
    As can be seen above the message context is unused and when I try to run my text I get a NullPointerException, and rightly so. Since there is no 'connection' between the context and my parser.

    It is quite mysterious to me how the XPath parsing works when deployed on a server, i.e how the 'connection' with the message context and the XPathExpresion is done and works fine.

    In MessageDispatcher's dispatch method, the invoke method is called to trigger the handle in my end point.

    Code:
    // Actually invoke the endpoint
                    EndpointAdapter endpointAdapter = getEndpointAdapter(mappedEndpoint.getEndpoint());
                    endpointAdapter.invoke(messageContext, mappedEndpoint.getEndpoint());
    But trying to resolve the implementation of the endpoint adapter only brings me to a set of deprecated abstract classes and the one which would suit my needs is AbstractJDomPayloadEndpoint.
    Are there any concrete implementations of this class?
    Anyone has a clue of how the XPath parsing works fine on server, and hence how can I adjust my unit test.

    Regards
    Kris

    Comment


    • #3
      Having found the solution, I thought I would add the code and it could probably be useful to somebody in the future

      Code:
      @Test
      	public void testParseMessage() throws Exception {
      		
      		SaajSoapMessageFactory messageFactory = new SaajSoapMessageFactory();
      		messageFactory.setSoapVersion(SoapVersion.SOAP_11);
      		messageFactory.afterPropertiesSet();
      		
      		InputStream inputStream = ClassLoader.getSystemResourceAsStream("findByCustomerIdRequest.xml");
      
      		WebServiceMessage request = messageFactory.createWebServiceMessage(inputStream);
      		MessageContext messageContext = new DefaultMessageContext(request , messageFactory);
      		
      		JDomPayloadMethodProcessor jDomPayloadMethodProcessor = new JDomPayloadMethodProcessor();
      		Class<? extends CustomerSearchEndPoint> customerSearchEndPointClass = new CustomerSearchEndPoint().getClass(); 
      		Method method = customerSearchEndPointClass.getMethod("findByNameLocationAndDepartment", new Class[]{Element.class});
      		MethodParameter parameter = new MethodParameter(method , 0);
      		Element customerSearchOptions = (Element) jDomPayloadMethodProcessor.resolveArgument(messageContext, parameter);
      		
      		
      		
      		customerSearchServicePathExpressionParser.getCustomerId(customerSearchOptions);
      		
      	}
      I found that Spring is creating the Element in DefaultMethodEndpointAdapter.getMethodArguments(), after following up the code through a remote debug.

      Comment

      Working...
      X