In this blog, software developers and architects who have a basic knowledge of the MuleSoft Anypoint development environment will learn useful development best practices about the MUnit 2 testing framework.
MUnit 2 Overview:
MUnit 2 is a Mule application testing framework that allows you to easily build automated tests for your integrations and APIs. It works with all Mule versions, including the more recent Mule 4. MUnit 2 is also fully integrated with Anypoint Studio, allowing you to create, design, and run MUnit tests just like you would with Mule applications.
With MUnit 2, you can create your test by writing Mule code, mocking processors, spying any processor, verifying processor calls, enabling or ignoring particular tests, tagging tests, checking visual coverage in Studio, and generating coverage reports.
- MUnit 2 provides a complete suite of integration and unit test capabilities.
- MUnit 2 is fully integrated with Maven and Surefire for integration with continuous deployment environments.
- MUnit 2 can reduce the need to manually verify the code every time by automating the verification process.
- MUnit 2 develops reusable code that, with some customization, can be applied in other projects.
How to make MUnit 2 work for you
- Understanding the MUnit 2 Object Model
The MUnit 2 framework enables developers to create test suites, which are grouped into unit tests as resources within the Mule project.
The following screenshot shows a sample of what these resources look like in the project. Each Test Suite results in a separate configuration file (like Mule Configuration files), where each test is analogous to an ordinary Process Flow.
- Structuring Test Suites
There are no rules for how you should organize your test suites.
Generally, test suites are organised in one of two ways:
- By functionality: One Test Suite corresponds to one functionality (e.g. Product, Sales, etc.) and may include more than one API.
- By interface (API): One Test Suite corresponds to a single API.
For us, the best way to structure Test Suites is by interface or API, as this approach allows for increased modularity, better maintenance, and easier development of microservices (think of each API as a microservice).
- MUnit 2 Message Processors to simulate dependencies with remote systems
The MUnit message processors allow you to:
- Simulate a specific behaviour for a message processor with a Mock Message Processor.
- Lay out a Mule message using the Set Message Processor.
- Define a verification to validate a message processor’s call with a Verify Message Processor.
- Validate the content and status of the Mule message with the Assert Message Processor.
- How to mock a Database Query
Create a groovy script as follows, named “mockDbRowScript” which, in this example, returns the proper structure:
LinkedList<CaseInsensitiveHashMap<String, String>> rSet = new
CaseInsensitiveHashMap<String, String> rowDataMap = new
rowDataMap.put(“DISTANCE”, “1.3 miles”);
rowDataMap.put(“ADDRESS2”, “Romeoville IL 60446”);
rowDataMap.put(“ADDRESS1”, “13546 State Route 30”);
rowDataMap.put(“SERVICES”, “Gift Cards”);
This is referenced from the mock code with a call to the “resultOfScript” function.
- Generating Test Suites with APIkit
There are two ways to test: Going through the APIkit router, or not going through the APIkit router.
- If you go through the APIkit router, you have a more complete test than if you do not; however, by not going through the router, you shield your test from API-related information––allowing you to test only the business logic of the API.
- In the MUnit configuration, set mock-connectors and mock-inbounds to false. you must manually set these values to false; otherwise the test does not work
When using MUnit for APIkit-based projects, the developer can right-click on the APIkit Router to generate useful test skeletons.
- Code Coverage of production code through a Test Case
- Acceptance Percentage:
Depending on the projects, reasonable numbers can be in the 80-90% range.
Provides a metric on how much of a Mule application code has been executed by a set of MUnit tests.
MUnit Coverage is based on the amount of message processors executed.
MUnit Coverage provides metrics for:- Application overall coverage
- Resource coverage: Refers to each Mule configuration file under src/main/app. Each of is considered a resource by MUnit Coverage.
- Flow coverage: Refers to any of the following Flows, Sub-flows, and Batch jobs.
- Code Coverage Output:
Properly configured, MUnit 2 can generate a coverage report in the “target” directory of your build. By default, the report comes in HTML format, you can also configure JSON format, which better supports automated tasks.
- Code Coverage POM configuration:
The code coverage behavior can be configured in the POM file using the Maven MUnit Plugin:
- Test your code using Maven
Maven is a software packaging framework that specifies how an application (usually Java) should be assembled, including any dependencies it may have.
By default, most Mule applications are built using Maven because of its many useful features, such as its efficient support of dependency management.
MUnit test cases are executed for every Maven build. For each and every code, check-in into the project code repository, such as SVN or GIT, the configured Jenkins JOB (a CI/CD process) is executed. Part of the configured JOB is to run the MUnit tests. If the test cases fail, the Maven build will also fail. If the test cases pass, the build will pass and the artifact will be moved to the artifact repository. This process will take place for every code check-in into the code repository.
The CI/CD (Continuous Integration / Continuous Deployment) process relies on tools like Maven to enable parallel and continuous code development and deployment.
- Testing with Command Line
MUnit allows tests to be run inside of MuleSoft Anypoint Studio, which is a useful step to perform while coding. However, prior to committing/pushing your software to the code repository, you need to test the MUnit artifacts in the same way they are going to be executed in the scope of your project. For example, you would need to test from the command line if you are using Jenkins.
Running a specific test suite from command line:
mvn clean test -Dmunit.test=<regex-test-suite>
Running test with regular expression:
mvn clean test -Dmunit.test=.*my-test.*
Run a specific test inside that test suite:
mvn clean test -Dmunit.test=<regex-test-suite>#<regex-test-name>
Skip MUnit Tests:
–DskipTests or –DskipMunitTests
- Use flow vars before testing for mock results.
- Use Assert Messages with a readable message.
- Use Verify call.
- Mock only outbound connectors, not flow references.
- Assert flow vars and mock results.
- Ensure you have meaningful assertions in your test flows. Including checking flow variable, checking a value from the mock response for a specific value, verifying processor invocations, and checking HTTP status codes.
Click here to see an example of the process of creating a series of MUnit tests, which are aimed at validating the behaviour of a simple code sample.
If you would like to find out more about the MUnit 2 testing framework, do give us a call at +44 (0)203 475 7980 or email us at firstname.lastname@example.org.
Other useful links: