Testing Sequences in WSO2 ESB
Apr 20, 2019 · 7 minute read · CommentsWSO2ESBEIUnit Test
This post is intended to present a project that could help with testing the mediation sequences created in WSO2 ESB Projects.
Using tools like SOAP UI and Postman, we can test our APIs and Proxies by issuing requests to them and validate the response of the services. As this gives us a good start point for testing the integrations, it doesn’t allow us to test the individual pieces that compose the integration, the mediation sequences.
Thinking on that the project WSO2UnitTesting was created. The project was based on the following blog post.
The project consists in a car file that needs to be deployed to WSO2 ESB/EI server where the artifacts that needs to be tested will be also deployed to. It provides an API that we will call in order to test the sequences.
The API receives a post request with a JSON payload that will contain the information required to test a sequence:
- payload: the payload that the sequence under testing is expecting to handle;
- requestType: the message type for the request payload, the input payload expected by the sequence, that can be xml or json;
- responseType: the message type for the response payload, the output payload after executing the sequence, that can be xml or json;
- properties: the properties that sequence under testing is expecting to handle.
- sequences: the name of the sequence that is going to be tested.
An example of a request can be seen below:
{
"payload" : "<abc xmlns=\"http://www.abc.com\"><text>123</text></abc>",
"requestType": "xml",
"responseType": "xml"
"properties": [
{
"name":"PROP1",
"value": "ABC",
"scope": "default",
"type":"STRING"
}
],
"sequences": [
"SequenceForTest"
]
}
The response has a similar structure, the only difference is that it will contain the payload and properties generated after the execution of the sequence.
Unit Test Example
As an example, we have built a sample app, that is a simple REST api around a Calculator SOAP Service. For the sake of the simplicity, we have create just one resource, /add that receives two numbers and returns a JSON with the result of the sum.
The resource is composed by the following sequences:
UnitTestExample_Validation_Sequence: it validates the resource parameters to check if they are numbers. It set a property VALIDATION_RESULT that can be FAILURE or SUCCESS. In case of validation failures, it sets another property VAL_ERROR_MESSAGE with the failure message;
UnitTestExample_BuildRequestPayload_Sequence: It builds the request payload to the target backend system using the two parameters received;
UnitTestExample_SendRequest_Sequence: It sends the request to the target system using a call mediator;
UnitTestExample_BuildResponsePayload_Sequence: It builds the JSON response with the result of the SOAP call to the target system;
The API Code can be seen below:
An example of the API call can be seen below:
http://localhost:8280/calculator/add/1/2
As we could see, it is a very simple example of a WSO2 ESB API.
Let us now work on the Unit Tests for the sequences created for this examples.
Pre-requisites for running the examples
In order to run the examples we need to:
- Clone the WSO2UnitTesting project: git clone https://github.com/fjunior87/WSO2UnitTesting.git
- Build it: cd WSO2UnitTesting; mvn clean install
- Deploy the car file into the WSO2 EI/ESB. It will be under WSO2UnitTesting/WSO2UnitTestCompositeApplication/target;
- Clone the Application Example: git clone https://github.com/fjunior87/WSO2UnitTestExample.git
- Build it: cd WSO2UnitTestExample; mvn clean install
- Deploy the car file into the WSO2 EI/ESB. It will be under WSO2UnitTestExample/WSO2UnitTestExampleAppCompositeApplication/target;
We also need the postman project that can be found in the example app: UnitTestExample.postman_collection.json.
You can import it to postman and then send the requests.
Unit Test Using Postman
For this post, I will use postman to issue the requests to our UnitTest API and also to validate the response, as it supports tests.
For the first example we will test the validation sequence for a Success scenario. We can see the sequence code below:
As we could see, the sequence expects two properties and validate if they are both numbers. Below we can see, what would be the payload to test the success scenario:
{
"payload" : "<empty/>",
"requestType": "xml",
"responseType": "xml",
"properties": [
{
"name":"uri.var.number1",
"value":"1",
"type": "STRING"
},
{
"name":"uri.var.number2",
"value":"2",
"type": "STRING"
}
],
"sequences": [
"UnitTestExample_Validation_Sequence"
]
}
Let us now describe the payload being passed for this test case:
- payload: We are passing an empty payload as this sequence doesn’t use any information of the payload;
- requestType and responseType: We are setting xml, for this test case it is not relevant as we are not using the payload information;
- properties: We are setting the two properties that the sequence is expecting to use: uri.var.number1 and uri.var.number2. We specify the type and the value for each of the properties;
- sequences: We define the name of the sequence that we will be testing, in this case: UnitTestExample_Validation_Sequence;
Using the payload above we will make a request to the following endpoint:
http://localhost:8280/unittest/test
The response payload will look like below:
{
"payload": "<empty/>",
"requestType": "xml",
"responseType": "xml",
"properties": [
{
"name": "number1_value",
"value": "1",
"type": "STRING",
"scope": "default"
},
{
"name": "uri.var.number2",
"value": "2",
"type": "STRING",
"scope": "default"
},
{
"name": "VALIDATION_RESULT",
"value": "SUCCESS",
"type": "STRING",
"scope": "default"
},
{
"name": "uri.var.number1",
"value": "1",
"type": "STRING",
"scope": "default"
},
{
"name": "number2_value",
"value": "2",
"type": "STRING",
"scope": "default"
}
],
"sequences": [
"UnitTestExample_Validation_Sequence"
]
}
It will basically contain the payload generated and the properties set after the execution of the sequence. In this case, it contains the properties that were used by the sequence as well the properties set after it, the most important property for our testing would be: VALIDATION_RESULT. Looking into the response payload we can see it was set as SUCCESS.
Once we have the request and response, we can use postman test scripts to assert the properties set and also the payload generated.
pm.test("response is ok", function () {
pm.response.to.have.status(200);
});
pm.test("VALIDATION_RESULT is SUCCESS", function () {
json = pm.response.json();
var prop = json.properties.find(prop => prop.name == 'VALIDATION_RESULT' && prop.scope == 'default');
pm.expect(prop.value).to.equal("SUCCESS");
});
Basically, this test is validation the status code, if it is 200, and if the property VALIDATION_RESULT is equal to ‘SUCCESS’
We can see an example of this test case execution below:
As we could see with this test, we were able to execute a sequence from our application passing all the expected properties.
In the next test case we will see an example of test passing an expected payload to a sequence.
In the test below we will be testing the sequence that generates the response payload based on the response got from the backend call. The test request can be seen below:
{
"payload" : "<AddResponse xmlns=\"http://tempuri.org/\"><AddResult>30</AddResult></AddResponse>",
"requestType": "xml",
"responseType": "json",
"properties": [],
"sequences": [
"UnitTestExample_BuildResponsePayload_Sequence"
]
}
In this test, we are not setting any property as it is not expected by the sequence being tested. We set only:
- payload: the xml expected by the sequence;
- requestType: xml, as the input payload is an xml;
- responseType: json, as the output payload is a json;
By executing this request we will receive a response like below:
{
"payload": "{\n\t\t\t\t\"result\": 30\n\t\t\t}",
"requestType": "xml",
"responseType": "json",
"properties": [],
"sequences": [
"UnitTestExample_BuildResponsePayload_Sequence"
]
}
And our Postman test will look like this:
pm.test("response is ok", function () {
pm.response.to.have.status(200);
});
pm.test("Response payload should have the result equals to 30", function () {
json = pm.response.json();
payload = JSON.parse(json.payload);
pm.expect(payload.result).to.equal(30);
});
That’s it for today.
In the postman project there are a couple of other test cases. If you want, you can also run the postman tests in the command line using Newman. Also, you could create your test cases using any other testing tool/framework like SOAPUI, RestAssured, Karate.
The source code of the unit test app and the example app can be found in the links below:
I hope you enjoyed and this can help you to increase the quality of your WSO2 EI projects!
See you in the next post.