To fully grasp what we will be covering you should have a basic knowledge of software testing and understand what the following terms mean:
Before we go into the details of mocking and simulating systems communicating via JMS, let us see what JMS actually is.
JMS is an API for asynchronous communication. You can send a message to a queue or a topic via JMS. For example, System A can send a JSON message to JMS queue called QUEUE1. Then, System B can consume that message from QUEUE1 whenever it wishes to. System A and System B can communicate that way without a time dependency, System A can send messages as often and as many as it wishes, and System B can consume then whenever its ready to do so.
When using queues, a message is sent by one system, and received by only one system. JMS also allows for a communication via topics, where one message sent by System A can be received by many systems System B, System C, etc.
For more details on JMS, please have a look at the JMS tutorial.
Many types of messaging systems expose a JMS API. For example, you will be able to connect to ActiveMQ and IBM® WebSphere MQ using the same JMS API.
Let us focus on a typical communication pattern where two systems communicate with request and response messages with an IBM® WebSphere MQ broker:
Now that we have two systems communicating with JMS messages, we can explore how we could test those systems. What happens if we wanted to test System A, but System B is temporarily unavailable? Or, what happens if System B does not exist yet at all?
In these scenarios, we can simulate System B using Traffic Parrot so that System A can still be tested. It will consume the request messages and produce response messages, pretending to be System B.
This will allow us to test System A in isolation in both typical and hypothetical situations. You will be able to simulate messages that are expected to be seen in production environments, but also non-typical error messages or failure scenarios that would usually be hard to produce. You can do that by configuring Traffic Parrot to respond with JMS response messages of your choice.
Let's go through an example of how to use Traffic Parrot to simulate a system that sends and receives IBM MQ messages. Our system under test is a Fruit Ordering System that is used to send "order fruit" messages, and an Order Processing System that receives an "order fruit" message, processes the order and sends an "order confirmation" message.
Now, in our example, we will assume that the Order Processing System is not available (for example, it is not yet developed or the environment is not yet configured). All we have is the documentation for it. How can we test the Fruit Ordering System in that situation, and where will the "order confirmation" messages come from if Order Processing System is not there?
We can simulate the Order Processing System using Traffic Parrot! Traffic Parrot will consume the order fruit messages and send order confirmation messages, pretending to be the Order Processing System. We will read the Order Processing System documentation to understand how to define the format of the order confirmation messages.
You can view the web user interface in the browser at http://localhost:8282.
The way the Fruit Order System works is that you submit an order for a certain number of fruit using the web user interface. It will then send a JMS request message to the Order Processing System. In the meantime it also awaits any JMS response messages and when it gets one it renders it on the web user interface. So when the Order Processing System is not available like in our scenario, there will never be anything displayed in the Order Confirmations section, but we still need to test that section!
{
"orderItemName": "apple",
"quantity": "3",
"date": "2017-12-14T14:15:21Z"
}
Based on that documentation fill in the request queue name, response queue name and response body.
Then, press the "Save" button.
The recommended way of creating mocks or stubs of third party or backed systems and APIs is
to keep them as simple as possible. Unfortunately, sometimes it is not
possible to keep things simple, and it is necessary to create more complex systems or API
simulators. In this example, we will go through an example how to create a simulator of an
IBM® WebSphere MQ JMS API that will dynamically generate a list of items in a response based on a request.
In the example above Traffic Parrot simulates the Order Processing System, but the JMS response message returned is always the same. So, regardless of what type of item and quantity we order the response message is always the same. Let us have a look at how to use Traffic Parrot to create a dynamic JMS response message!
To use request data in response we will use the handlebar helpers. We will use request.body to access the body of the JMS request message and then use jsonPath to extract bits of the JSON content {{jsonPath request.body '$.foo.bar'}}
To simulate the Order Processing System using Traffic Parrot and generate dynamic JMS response messages:
{
"quantity": "3",
"orderItemName": "apple"
}
so we can now extract data and put it in the JMS response message using jsonPath like this
{{jsonPath request.body '$.quantity'}} and
this {{jsonPath request.body '$.orderItemName'}}
We can also generate a dynamic date in the correct format using
{{now format="yyyy-MM-dd'T'HH:mm:ssZ"}}