In this article, I want to show you how you can create and configure API helpers using Java and the Citrus Integration Framework. Further helpers can already be used in a test project to send a request to the desired interface and, accordingly, receive a response with further validation of the obtained data.
We will look at helpers for such system interfaces as: REST, SOAP and WebSocket services. I think they are the most popular and we encounter them more often than others in testing.
Below is a call to the REST service:
@Test()
@CitrusTest
public void getTestActions() {
this.context = citrus.createTestContext();
http(httpActionBuilder -> httpActionBuilder
.client("httpHelperClient")
.send()
.get("users"));
http(httpActionBuilder -> httpActionBuilder
.client("httpHelperClient")
.receive()
.response(HttpStatus.OK)
.messageType(MessageType.JSON)
.payload(getJsonData(), "objectMapper"));
}
I also show you how to configure the client "bean" and "objectMapper" in the citrus-context.xml file. This client can then be used in the helper to send the request, and the "objectMapper" can be used for serialization and deserialization.
<!--HTTP-Helper-->
<citrus-http:client
id="httpHelperClient"
request-url="${url}"
content-type="application/json"
timeout="30000"/>
<bean id="objectMapper" class="com.fasterxml.jackson.databind.ObjectMapper">
<property name="serializationInclusion" value="NON_NULL"/>
</bean>
Below is a call to the SOAP service:
@Test()
@CitrusTest
public void getTestActions() {
this.context = citrus.createTestContext();
PojoToXML<Class<NumberToDollars>> convRequest = new PojoToXML<>();
PojoToXML<Class<NumberToDollarsResponse>> convResponse = new PojoToXML<>();
soap(soapActionBuilder -> soapActionBuilder
.client("soapHelperClient")
.send()
.payload(convRequest.convert(NumberToDollars.class, getNumberToDollarsRequest(), "http://www.dataaccess.com/webservicesserver/", "NumberToDollars" ))
);
soap(soapActionBuilder -> soapActionBuilder
.client("soapHelperClient")
.receive()
.xsdSchemaRepository("schemaRepositoryService")
.payload(convResponse.convert(NumberToDollarsResponse.class, getNumberToDollarsResponse(), "http://www.dataaccess.com/webservicesserver/", "NumberToDollarsResponse"))
);
}
In this code i use my custom Marshaler named PojoToXML. Code below:
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.namespace.QName;
import java.io.IOException;
import java.io.OutputStream;
public class PojoToXML<T> {
public T generic;
public String convert(T requestClass, Object requestData, String namespaseURI, String localPart) { //namespaseURI=http://oms.rt.ru/ , localPart=submitOrderRequest
generic = requestClass;
String s = null;
try {
JAXBContext jaxbContext = JAXBContext.newInstance((Class) requestClass);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
// To format XML
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
JAXBElement<T> jaxbElement =
new JAXBElement<T>(new QName(namespaseURI, localPart),
(Class) requestClass,
(T) requestData);
OutputStream output = new OutputStream() {
private StringBuilder string = new StringBuilder();
@Override
public void write(int b) throws IOException {
this.string.append((char) b );
}
public String toString(){
return this.string.toString();
}
};
jaxbMarshaller.marshal(jaxbElement, output);
s = String.valueOf(output);
} catch (JAXBException e) {
e.printStackTrace();
}
return s;
}
}
I also show how to configure the client "bean" and additional settings for working with xml in the citrus-context.xml file.
<!--SOAP-Helper-->
<citrus-ws:client
id="soapHelperClient"
request-url="${urlSOAP}"
timeout="30000"/>
<!--For SOAP 1.1-->
<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory">
<property name="soapVersion">
<util:constant static-field="org.springframework.ws.soap.SoapVersion.SOAP_11"/>
</property>
</bean>
<citrus:schema-repository id="schemaRepositoryService">
<citrus:schemas>
<citrus:schema id="DATAACCESS" location="classpath:wsdl/numberconversion.wsdl" />
</citrus:schemas>
</citrus:schema-repository>
Below is a call to the WebSocket service:
@Test()
@CitrusTest
public void getTestActionsWSS(){
this.context = citrus.createTestContext();
send(action -> action
.endpoint("wssHelperClient")
.fork(true)
);
receive(action -> action
.endpoint("wssHelperClient")
.messageType(MessageType.JSON)
.payload(getJsonDataResponseWSS(), "objectMapper")
);
}
I also show you how to configure the client "bean" in the citrus-context.xml file and you should add an "objectMapper" in case of interaction by JSON messages.
<!--WSS-Helper-->
<citrus-websocket:client
id="wssHelperClient"
url="${urlWSS}"
timeout="30000"/>
<bean id="objectMapper" class="com.fasterxml.jackson.databind.ObjectMapper">
<property name="serializationInclusion" value="NON_NULL"/>
</bean>
To summarize, in each case we create two "actions", one action to send a request and the second to receive a response and then validate the data. In general, this is all for helpers now. I hope my examples help you.