Spring Web Services: Client Integration Testing with MockWebServiceServer

Spring Web Services provides a great way to perform web service client integration tests. However, the example in the documentation requires the client class to extend org.springframework.ws.client.core.support.WebServiceGatewaySupport, which is rather ugly. Instead, I prefer to have WebServiceTemplate injected into my client class.

So, I made a slight tweak to my integration test to work this work…

Production Code To Be Tested

First, we need the following Spring Web Services dependency:

<dependency>
    <groupId>org.springframework.ws</groupId>
    <artifactId>spring-ws-core</artifactId>
    <version>2.1.4.RELEASE</version>
</dependency>

Let’s assume the client class looks like this:-

@Service
public class WSClientServiceImpl implements WSClientService {

    private WebServiceTemplate webServiceTemplate;

    @Autowired
    public WSClientServiceImpl(WebServiceTemplate webServiceTemplate) {
        this.webServiceTemplate = webServiceTemplate;
    }

    public String login(String username, String password) {
        Login login = new ObjectFactory().createLogin();
        login.setUsername(username);
        login.setPassword(password);

        SoapActionCallback callback = new SoapActionCallback("http://webservice/login");
        Object object = webServiceTemplate.marshalSendAndReceive(login, callback);

        JAXBElement<String> jaxbElement = (JAXBElement<String>) object;
        String sessionId = jaxbElement.getValue();

        return sessionId;
    }
}

The WebServiceTemplate bean is configured like this:-

<beans ...>
    <context:component-scan base-package="com.choonchernlim.epicapp"/>

    <bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
        <property name="contextPaths">
            <list>
                <value>...</value>
            </list>
        </property>
    </bean>

    <bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
        <property name="marshaller" ref="marshaller"/>
        <property name="unmarshaller" ref="marshaller"/>
        <property name="defaultUri" value="http://webservice"/>
    </bean>
</beans>

Constructing Integration Test

Make sure we have the Spring Web Services Test framework dependency:-

<dependency>
    <groupId>org.springframework.ws</groupId>
    <artifactId>spring-ws-test</artifactId>
    <version>2.1.4.RELEASE</version>
    <scope>test</scope>
</dependency>

The integration test looks similar to the example in the Spring documentation, however, I injected WebServiceTemplate instead:-

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath*:applicationContext.xml"})
public class WSClientServiceImplTest {

    @Autowired
    private WSClientService wsClientService;

    @Autowired
    private WebServiceTemplate webServiceTemplate;

    private MockWebServiceServer mockServer;

    @Before
    public void createServer() throws Exception {
        mockServer = MockWebServiceServer.createServer(webServiceTemplate);
    }

    @Test
    public void testLogin() {
        Source requestPayload = new StringSource(
                "<ns2:Login xmlns:ns2='http://webservice/login'>" +
                "  <ns2:Username>user</ns2:Username>" +
                "  <ns2:Password>password</ns2:Password>" +
                "</ns2:Login>"
        );

        Source responsePayload = new StringSource(
                "<SessionID xmlns='http://webservice/login'>12345</SessionID>"
        );

        mockServer.expect(payload(requestPayload)).andRespond(withPayload(responsePayload));

        String sessionId = wsClientService.login("user", "password");

        assertThat(sessionId, is("12345"));

        mockServer.verify();
    }
}

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s