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">
</property></property></property></bean>
</context:component-scan></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();
}
}
Leave a Reply