How to create a mock for Spring WebServiceTemplate?

I have a class that calls an existing web service. My class handles valid results correctly, as well as error strings generated by the web service. The main web service call looks something like this (although this is simplified).

public String callWebService(final String inputXml) { String result = null; try { StreamSource input = new StreamSource(new StringReader(inputXml)); StringWriter output = new StringWriter(); _webServiceTemplate.sendSourceAndReceiveToResult(_serviceUri, input, new StreamResult(output)); result = output.toString(); } catch (SoapFaultClientException ex) { result = ex.getFaultStringOrReason(); } return result; } 

Now I need to create some unit tests that check all successful and unsuccessful conditions. It cannot invoke the actual web service, so I was hoping there were mock objects for the client side of Spring -WS. Does anyone know of mock objects available for WebServiceTemplate or any related classes? Should I just try to write my own and change my class to use the WebServiceOperations and WebServiceTemplate interface?

+6
java spring-ws mocking
source share
2 answers

Michael answers very closely, but here is an example that works.

I already use Mockito for my unit tests, so I am familiar with the library. However, unlike my previous experience with Mockito, just mocking the result of the return does not help. I need to do two things to check all use cases:

  • Change the value stored in StreamResult.
  • Throw a SoapFaultClientException.

First, I needed to understand that I could not scoff at WebServiceTemplate with Mockito, since this is a specific class (you need to use EasyMock, if necessary). Fortunately, a call to the sendSourceAndReceiveToResult web service is part of the WebServiceOperations interface. This required a change in my code in order to expect WebServiceOperations and WebServiceTemplate.

The following code supports the first use case when the result is returned in the StreamResult parameter:

 private WebServiceOperations getMockWebServiceOperations(final String resultXml) { WebServiceOperations mockObj = Mockito.mock(WebServiceOperations.class); doAnswer(new Answer() { public Object answer(InvocationOnMock invocation) { try { Object[] args = invocation.getArguments(); StreamResult result = (StreamResult)args[2]; Writer output = result.getWriter(); output.write(resultXml); } catch (IOException e) { e.printStackTrace(); } return null; } }).when(mockObj).sendSourceAndReceiveToResult(anyString(), any(StreamSource.class), any(StreamResult.class)); return mockObj; } 

Support for the second use case is similar, but requires throwing an exception. The following code throws a SoapFaultClientException that contains a faultString. The error code is used by the code I'm testing, which processes the web service request:

 private WebServiceOperations getMockWebServiceOperations(final String faultString) { WebServiceOperations mockObj = Mockito.mock(WebServiceOperations.class); SoapFault soapFault = Mockito.mock(SoapFault.class); when(soapFault.getFaultStringOrReason()).thenReturn(faultString); SoapBody soapBody = Mockito.mock(SoapBody.class); when(soapBody.getFault()).thenReturn(soapFault); SoapMessage soapMsg = Mockito.mock(SoapMessage.class); when(soapMsg.getSoapBody()).thenReturn(soapBody); doThrow(new SoapFaultClientException(soapMsg)).when(mockObj).sendSourceAndReceiveToResult(anyString(), any(StreamSource.class), any(StreamResult.class)); return mockObj; } 

Both of these use cases may require additional code, but they work for my purposes.

+7
source share

Actually, I don’t know if pre-configured Mock objects exist, but I doubt that they are configured for all your “failure conditions”, so you can create a special Application> for your JUnit test with a replacement or work with the Framework framework. it's not that hard :-)

I used the Mockito Mock Framework as an example (and typed it quickly), but EasyMock , and your preferred framework should also do this

 package org.foo.bar import java.util.ArrayList; import java.util.List; import org.junit.Before; import org.junit.Test; import static org.mockito.Mockito.*; import static org.junit.Assert.*; public class WebserviceTemplateMockTest { private WhateverTheInterfaceIs webServiceTemplate; private TestClassInterface testClass; private final String inputXml = "bar"; @Test public void testClient(){ // assertTrue("foo".equals(testClass.callWebService(inputXml)); } /** * Create Webservice Mock. */ @Before public void createMock() { // create Mock webServiceTemplate = mock(WhateverTheInterfaceIs.class); // like inputXml you need to create testData for Uri etc. // 'result' should be the needed result data to produce the // real result of testClass.callWebService(...) when(webServiceTemplate.sendSourceAndReceiveToResult(Uri, inputXml, new StreamResult(output))).thenReturn(result); // or return other things, eg // .thenThrow(new FoobarException()); // see mockito documentation for more possibilities // Setup Testclass TestClassImpl temp = new TestClassImpl(); temp.setWebServiceTemplate(generatedClient); testClass = temp; } } 
+4
source share

All Articles