Saturday, March 26, 2011

Testing Spring Web Service endpoint

In previous post we have covered very interesting approach to build SOAP web services using lightweight by very powerful Spring Web Services framework. To wrap it up, let me show how easy you can test your web services.

Let me start with Spring context for test case (which is 99% the copy-paste from previous post).



    

    
 
    

    
        
            
                
             
        
        
            
                
            
        
     
 
    

    
         

Let us save this context to /src/test/resources/META-INF/spring-context.xml. There are two minor differences (comparing to initial one):
  • element <ws:static-wsdl/> has been removed
  • element <bean id="schema" ... /> has been added
Having context prepared, let us move on to test case itself.
package org.example;

import static org.springframework.ws.test.server.ResponseMatchers.validPayload;
import static org.example.SoapActionRequestCreator.withPayload;

import java.io.IOException;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.ws.test.server.MockWebServiceClient;

@RunWith( SpringJUnit4ClassRunner.class )
@ContextConfiguration( locations = "/META-INF/spring-context.xml" )
public class UserProfileEndpointTestCase {
    @Autowired private ApplicationContext applicationContext;
    @Autowired private Resource schema;
 
    private MockWebServiceClient client; 

    @Before
    public void setUp() {
        client = MockWebServiceClient.createClient( applicationContext );
    }
   
    @Test
    public void testServiceCall() throws IOException {
        final Resource payload = applicationContext.getResource( "Request.xml" );
  
        client.sendRequest( withPayload( "UserProfile", request ) ).   
            andExpect( validPayload( schema ) ); 
    }
}
This particular example does send request to SOAP web service and ensures that response is valid (against XSD schema), all that by leveraging Spring Web Services test scaffolding. There is one class which requires a bit of explanation: org.example.SoapActionRequestCreator. Nevertheless Spring Web Services provides rich set of payload builders, I didn't find the one which allows to pass SOAP action into request. So this small utility class has been developed. Here is a code for it:
package org.example;

import java.io.IOException;

import org.springframework.core.io.Resource;
import org.springframework.util.Assert;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.WebServiceMessageFactory;
import org.springframework.ws.soap.SoapMessage;
import org.springframework.ws.test.server.RequestCreator;
import org.springframework.ws.test.support.creator.PayloadMessageCreator;
import org.springframework.ws.test.support.creator.WebServiceMessageCreator;
import org.springframework.xml.transform.ResourceSource;

public class SoapActionRequestCreator implements RequestCreator {
    private final WebServiceMessageCreator adaptee;
    private final String action;
 
    private SoapActionRequestCreator ( final String action, 
            final WebServiceMessageCreator adaptee ) {
        this.action = action;
        this.adaptee = adaptee;
    }

    public static RequestCreator withPayload( final String action, 
            final Resource payload )throws IOException {
        Assert.notNull(payload, "'payload' must not be null");
        return new SoapActionRequestCreator( 
            action, new PayloadMessageCreator( new ResourceSource( payload ) ) );
    }
   
    @Override
    public WebServiceMessage createRequest( 
            final WebServiceMessageFactory messageFactory ) throws IOException {
        final WebServiceMessage message = adaptee.createMessage( messageFactory );
        Assert.isInstanceOf( SoapMessage.class, message );

        if( message instanceof SoapMessage ) {
            ( ( SoapMessage )message ).setSoapAction( action );
        }
  
        return message;
    }
}
This is just a very basic example. There are a bunch of tests you can do to ensure your SOAP web service performs as expected. I encourage to explore Spring Web Services documentation. All that should help us to develop high quality code and be proud of it.

No comments: