Overview

Mule ESB Testing (Part 3/3): System End-to-End Testing with Docker

No Comments

As generally acknowledged testing is an important part of the software development process. Tests should be applied during each phase of the software development process from developer tests to acceptance tests. In software engineering comprehensive and automated test suits will secure the quality of software and can provide a safety net for regression and incompatible changes.

In Mule ESB integration projects these same issues arise. Components used in Mule flows, the flows themselves and the integration of flows in a system context need to be tested thoroughly.

This article is the last one in a series of articles about testing Mule ESB projects on all levels (part 1, part 2). It is focusing on the overall system end-to-end test in a Mule project which is performed by setting up the infrastructure with the ESB and a mock server using Docker.

Infrastructure

To perform a system end-to-end test for a Mule application we need at least three different system components:

  • App: First of all we need the Mule application under test.
  • Tester: The testing part performs testing of the application under test. Such testing can be performed by simple tests which perform API calls and verify the results or complex orchestrated calls with a testing tool such as JMeter.
  • Mock: Then we need one or multiple system mocks, which represent the systems the application is dependent on. Mountebank can provide such functionality.

Such a system end-to-end setup would look like this:

system ed-to-end

Docker

Docker is an Open Source technology which allows the virtualization of machines as isolated containers on the host system. It provides the fast and resource efficient creation of containers on a host by using Linux technologies such as cgroups and namespaces. This enables the creation of portable, reproducible and immutable infrastructures. These are a huge bonus for the creation, reproducible execution of test scenarios which include infrastructure.

For a better integration of such a system end-to-end test into a continuous integration pipeline the usage of containerization technology is an advantage. Usage of Docker for example, will allow the fast start up and stopping of an isolated Mule instance with the application and a mock server.

Application under test

Let’s assume for example the following simple scenario. A Mule application provides a REST API on port 8080 which internally calls another backend REST service on port 9000. Such an application could look like that:

Bildschirmfoto 2015-06-09 um 22.24.31

We see in this example an HTTP endpoint which listens on port 8080 and routes all requests to an REST API router. The request to the /myResource will go into the bottom sub flow and will trigger an outbound HTTP call to a server on port 9000. The result is transformed into a string and returned to the caller afterwards. In case of exceptions, an exception strategy will return the approriate result.

We assume we have set up our Mule application already as a single application in a Docker container, as described in this blog post.

Mock server

To allow the Mule application to perform calls to potential backend services in a system end-to-end scenario, a technology such as Mountebank can be used.

Mountebank is an open source tool, which provides cross-platform, multi-protocol test doubles on a network. An application which is supposed to be tested, just needs to point to the IP or URL of a Mountebank instance instead of the real dependency. It allows to test your application through the whole application stack, as you would with traditional stubs and mocks. Supported protocols include HTTP, HTTPS, TCP and SMTP.

For our scenario, the Mountebank imposter would be defined as followed, returning a mocked response on port 9000:

{
  "port": 9000,
  "protocol": "http",
  "name": "My Mock",
  "mode": "text",
  "stubs": [
    {
      "responses": [
        {
          "is":
          {
            "statusCode": 200,
            "headers": {
              "Content-Type": "application/json"
            },
            "body": "{ \"message\": \"You got mocked data\" }"
          }
        }
      ],
      "predicates": [
        {
          "equals": {
            "path": "/anotherResource"
          }
        }
      ]
    }
  ]
}

We assume we have set up our mock server in a Docker container as well, as described in this blog post.

Test Definition

Now to define our test, we use a simple JUnit integration test using the rest-assured library integrated into a Maven build. It’s calling the REST API and verifying that the result is the mocked data from the mock server. At that point calls to the mock server via the Mountebank REST API can be performed for verification purposes as well.

Comment

Your email address will not be published. Required fields are marked *