JUnit testing with Spring Integration and Spring WS
Join the DZone community and get the full member experience.
Join For FreeAs a first step we need to define the XSD schema:
<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:data="http://mycompany.com/it/enterprise/data/v1" xmlns:msg="http://mycompany.com/it/enterprise/msg/v1" xmlns:svc="http://mycompany.com/it/enterprise/contract/TestService/v1" targetNamespace="http://mycompany.com/it/enterprise/contract/TestService/v1" elementFormDefault="qualified" attributeFormDefault="unqualified" version="1.0"> <xsd:import namespace="http : //mycompany.com/it/enterprise/data/v1" schemaLocation="TestTransactions_v1.xsd"/> <xsd:element name="TestServiceRequest" type="data:TestServiceRequestType"/> <xsd:element name="TestServiceResponse" type="data:TestServiceResponseType"/> </xsd:schema> <?xml version="1.0" encoding="UTF-8"?><xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:data="http://mycompany.com/it/enterprise/data/v1" xmlns:msg="http://mycompany.com/it/enterprise/msg/v1" targetNamespace="http://mycompany.com/it/enterprise/data/v1" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xsd:complexType name="TestServiceRequestType"> <xsd:sequence> <xsd:element name="Document"> <xsd:complexType> <xsd:sequence> <xsd:element name="Id" type="xsd:string" minOccurs="0"/> <xsd:element name="Type" type="xsd:string" minOccurs="0"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> <xsd:complexType name="TestServiceResponseType"> <xsd:sequence> <xsd:element name="Document"> <xsd:complexType> <xsd:sequence> <xsd:element name="Result" type="xsd:string" minOccurs="0"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:schema>
Writing the JUnit test as below,
public class TestIntegrationEndPointTest { @Autowired private ApplicationContext applicationContext; private MockWebServiceClient mockClient; @Before public void createClient() { mockClient = MockWebServiceClient.createClient(applicationContext); } @Test public void testWsEndPointTest() throws Exception { Source requestPayload = new StringSource("<?xml version=\"1.0\" encoding=\"UTF-8\"?><v1:TestServiceRequest xmlns:v1=\"http://mycompany.com/it/enterprise/contract/TestService/v1\" xmlns:v11=\"http://mycompany.com/it/enterprise/data/v1\"><v11:Document><v11:Id>101</v11:Id><v11:Type>MaterialMaster</v11:Type></v11:Document></v1:TestServiceRequest>"); Source responsePayload = new StringSource("<testServiceResponseType xmlns=\"http://mycompany.com/it/enterprise/data/v1\" xmlns:ns2=\"http://mycompany.com/it/enterprise/contract/TestService/v1\"><Document><Result>SUCCESS</Result></Document></testServiceResponseType>"); mockClient.sendRequest(withPayload(requestPayload)).andExpect(payload(responsePayload)); } }
Now the test will still fail with need for Spring autowiring, the spring bean definition configuration for Spring WS looks as below,
<bean> <property name="endpointMap"> <map> <entry key="{http://mycompany.com/it/enterprise/contract/TestService/v1}TestServiceRequest" value-ref="TestBatchEndpoint" /> </map> </property> </bean> <int-ws:inbound-gateway id="TestBatchEndpoint" reply-channel="test.batch.webservice.out" request-channel="test.batch.webservice.in" /> <bean id="marshaller" > <property name="contextPath" value="com.mycompany.it.enterprise.contract.testservice.v1" /> </bean> <bean id="testServiceActivator" class="com.mycompany.it.eis.webservice.ws.TestServiceActivator"/> <bean id="resultTransformer" class="org.springframework.integration.xml.transformer.ResultToStringTransformer"/>
Spring Integration and Spring WS flow looks as below
<int:bridge input-channel="test.batch.webservice.in" output-channel="test.batch.webservice.unmarshalling.in"></int:bridge> <int-xml:unmarshalling-transformer id="defaultUnmarshaller" input-channel="test.batch.webservice.unmarshalling.in" output-channel="test.batch.webservice.unmarshalling.out" unmarshaller="marshaller"/> <int:service-activator id="test.batch.webservice.activator" input-channel="test.batch.webservice.unmarshalling.out" ref="testServiceActivator" output-channel="test.batch.webservice.marshalling.in"> </int:service-activator> <int-xml:marshalling-transformer input-channel="test.batch.webservice.marshalling.in" output-channel="test.batch.webservice.out" marshaller="marshaller" result-transformer="resultTransformer" />
IBatisTemplate looks as below,
<bean id="sqlMapClientTemplate" class="org.springframework.orm.ibatis.SqlMapClientTemplate">> <property name="sqlMapClient" ref="sqlMapClient" /> </bean>
You need to create the Java stubs from the XSL for that you need to run,
mvn jaxb2:xjc
It assumes that you have XSDs at location src/main/xsd location by default, refer this article for more details.
In the Test class, you need to add the Spring JUnit testing capabilities as follows,
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration({ "classpath:META-INF/spring/test-webservice/test-webservice-integration-config.xml", "classpath:config/test-webservice-beans-config-test.xml" }) public class TestIntegrationEndPointTest {
TestServiceActivator looks somewhat as below:
public class TestServiceActivator { private static Logger logger = Logger.getLogger(TestServiceActivator.class); @Autowired SqlMapClientTemplate ibatisTemplate; public TestServiceResponseType processRequest(JAXBElement element) throws Exception { TestServiceRequestType request = (TestServiceRequestType) element.getValue(); String status = "SUCCESS"; String type = request.getDocument().getType(); String id = request.getDocument().getId(); TestObject notifyObject = new TestObject(); notifyObject.setId(id); notifyObject.setType(type); ibatisTemplate.insert("testInsert", notifyObject); TestServiceResponseType response = new TestServiceResponseType(); Document doc = new Document(); doc.setResult(status); response.setDocument(doc); logger.debug("Successfully saved request"); return response; } }
One hack we need to do is, we need to add @XmlRootElement to the stubs that were created as per this article
@XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "TestServiceResponseType", propOrder = { "document" }) public class TestServiceResponseType { @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "TestServiceRequestType", propOrder = { "document" }) public class TestServiceRequestType {
Once you do this, we can run the mvn test and it will work. If you notice in this example, we have tested the String WS end to end using JUnit and Spring Integraiton.
For further reading refer http://blog.springsource.org/2011/01/11/spring-web-services-2-0-released/ .
Published at DZone with permission of Krishna Prasad, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments