AVIO Insights

Understanding the Mule Groovy Testing Framework

Unit testing is a crucial part of the software development cycle. It involves testing individual modules to determine whether or not they are working correctly. During test case execution, frameworks continuously register the test status, report bugs, and fix defects.

When writing test cases, developers can use several automated testing tools depending on their programming needs. Java programmers, for instance, use the Junit framework to write tests on Java while Mulesoft’s native framework, MUnit tests, allows programmers to write automated tests for integrations and APIs.

Both MUnit and Junit test classes are great for developers, but we will just discuss the Mule Groovy testing framework in this entry. 

What makes the Mule Groovy testing framework superior is the fact that it has more functionalities. It’s also straightforward since its base test class extends Mule MUnit and Junit’s test classes.

Generating the PKCS#12 Keystore

The groovy component is quite similar to other programming components like Java, Rudy, or Python. It provides users with facilities to help them integrate custom scripts in flows. 

This guide is about showing you how Groovy makes Mule unit testing quite easy and convenient for programmers. Below is a highlight of the features supported:

  • Mocking VM Puts
  • Invoking flows in APIkit Router
  • Handling marshaling and unmarshaling in JAXB and Mocking SOAP integration connectors
  • Mocking a REST API interaction using HTTP requests with either XML or JSON responses formats
  • Solving XML problems in JAXB
  • Automatically validating HTTP status codes and content type
  • Handle streaming in Mule Apps
  • HTTP response validation (path, query, URI, and verbs params)
  • Mocking DQL and Devkit-based connectors
  • Load Mule configure files automatically from mule-deploy.properties and enables substituting

As mentioned earlier, this testing framework has several features that differ from MUnit. These are:

  • The framework supports the Groovy scripts natively
  • It allows validation of Data Query Language (DQL) based queries
  • It enables users to validate HTTP path variables and query parameters

With the above in mind, here are some examples of tests that are yet to be done using this testing framework:

  • Mocking DB
  • How to generate unit tests boilerplate code
  • Differentiating maven dependency conflicts with spot loader overrides issues

Setting up your project

Maven Set-up

  • First, install the groovy eclipse plugin in your .m2 repository
  • Then add this folder: src/test/groovy to compile the tests
<plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.1</version>
    <configuration>
        <compilerId>groovy-eclipse-compiler</compilerId>
    </configuration>
    <dependencies>
        <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-eclipse-compiler</artifactId>
            <version>2.9.2-01</version>
        </dependency>
        <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-eclipse-batch</artifactId>
            <version>2.4.3-01</version>
        </dependency>
    </dependencies>
</plugin>
...
<dependencies>
    <dependency>
        <groupId>org.codehaus.groovy</groupId>
        <artifactId>groovy-all</artifactId>
        <version>2.4.3</version>
        <!-- Doesn't need to be deployed in ZIP -->
        <scope>provided</scope>
    </dependency>
</dependencies>
  • The next step is to add dependencies of your test framework to your Mule project’s pom.xml as illustrated below:
<dependency>
    <groupId>com.avioconsulting.mule</groupId>
    <artifactId>testing</artifactId>
    <version>1.0.13</version>
    <scope>test</scope>
</dependency>
  • As you do this, don’t forget to add the respective jsonschema2pojo-maven-plugin or jaxb2-maven-plugin usages for test sources.
  • If you’ve carefully followed the steps above, you are now ready to create your test classes.

Please note that if you are doing a SOAP project (which uses Mule applications), using XMLBeans, you might notice some performance issues with an XML schema or WSDL specifications when you enable JVM assertions. Since this testing approach relies on Surefire, you can keep assertions disabled using the plugin snippet below, although Surefire usually takes care of this command by default.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.22.0</version>
    <configuration>
        <!-- XMLBeans and some schemas have performance issues when running tests with assertions enabled -->
        <enableAssertions>false</enableAssertions>
    </configuration>
</plugin>

Groovy test classes

Loading

For your project to be a success, you have to create a base class that extends BaseTest. To exclude Mule configuration files from mule-deploy.properties, override the getConfigResourceSubstitutes as shown in the method below:

@Override
Map<String, String> getConfigResourceSubstitutes() {
    // this example will prevent global.xml from loading and load global-test.xml instead
    // it will also prevent foo.xml from loading and will load nothing in its place
    ['global.xml': 'global-test.xml',
    'foo.xml'   : null]
}

The idea here is to test whether mule-deploy.properties has the correct entities.

Testing MuleSoft APIKit

Since this testing framework supports APIKit, it's easy to perform test cases through the APIkit router. This test will serve the following purposes:

  • Validate your RAML, which might be used by APIkit router
  • Validate the existence of generated flows like post:/…
  • To provide an “end-to-end” testing

For the testing framework to function properly, consider having the following:

  • An active Mule HTTP listener. The framework will find an open port and configure the listener automatically. 
  • You need to set properties, such as path, HTTP host, etc., that are normally set by the HTTP listener to allow APIkit router to route invoke your flows properly
  • You must invoke the main flow of the router

This test works with assumptions that:

  • The config-ref of your HTTP listener is already set to ${http.listener.config}
  • The config of your HTTP listener is in global.xml. This makes sure that it cannot be overridden.
  • HTTP listener path is set in this form: /app-name/api/v1/*: where app-name and v1 are the values from getApiNameUnderTest and getApiVersionUnderTest, respectively.
  • The name of your main flow is in this form: api-app-name-v1-main.

Usage

For usage, extend your base tests to BaseApiKitTest rather than BaseTest. To make this happen, you need to implement abstract methods for your API’s name and version.

Here is how to invoke it:

runApiKitFlow('PATCH', '/mappings') {
    json {
        inputOnly(mappings)
    }
    withOutputHttpStatus { Integer actualStatus ->
        httpStatus = actualStatus
    }
}

After writing tests using Groovy components, developers can find it challenging to continue writing test cases in Java. Although it requires you to extend test classes, the testing framework works perfectly. Just try it and see how convenient it can be for you. 

AVIO Consulting provides the formula to accelerate digital evolution and innovation. We offer thought leadership and proven practices for modern software development as well as a highly productive delivery team focused on enterprise integration with the MuleSoft platform.

New call-to-action

4 minute read