Mastering MUnit: A Comprehensive Guide to MuleSoft Testing (part – 1)

Validation of the smallest unit of code to verify if it works as expected is called Unit testing. Collaboration of these unit tests together results in a single system and provides an idea of how it behaves. Each developer should do unit testing of the code and it can be done in two ways.

Mastering MUnit: A Comprehensive Guide to MuleSoft Testing (part – 1)

Unit Testing 

Validation of the smallest unit of code to verify if it works as expected is called Unit testing. Collaboration of these unit tests together results in a single system and provides an idea of how it behaves. Each developer should do unit testing of the code and it can be done in two ways. 

                                   1. Manual Testing  

                                   2. Test driven development to automate test cases using frameworks like Munit. 

MUnit                

Munit is a mule application testing framework that allows you to easily build automated tests for your integrations and APIs. Munit framework provides a full suite of integration and unit test capabilities, and it's fully integrated with maven for continuous deployment environment. 

With MUnit you can 

  • Create your test by writing Mule code 
  • Mock processors  
  • Spy any processor  
  • Verify processor calls  
  • Enable or ignore tests 
  • Tag tests, check visual coverage in Studio and Generate coverage reports 

MUnit is divided in two main sub modules 

                1.MUnit 

                2.Munit Tools 

Each module has its own dependency and its look like below. 

 

MUnit module connectors 

  • Operations  

                  Set Events 

                  Set Null Payload 

  • Scopes And Routers  

                  Before Suite  

                  After Suite  

                  Before Test 

                  After Test 

                  Test 

Munit Tools Module Connectors 

  • Operations  

                  Assert equals, Assert that, Assert expression 

                  Mock When 

                  Verify Call 

                  Run Custom 

                  Fail 

                  Clear stored data, Dequeue, queue, Remove, Retrieve, sleep, store, store oauth token 

  • Scopes And Routers  

                  Spy 

 

Let us try a simple example. 

Create a mule demo project as usual like, 

 

After Creating a flow do Right click -> Munit-> Create Munit for this flow. 

It will be created as shown in the image. 

 

 
The Execution section in MUnit is the command center, directing the initiation and validation of Mule application tests. It orchestrates test scenarios, defining parameters, triggering test cases, and analyzing results. Essentially, it forms the pivotal bridge between test configuration and the actual execution, ensuring thorough validation and precise control of the testing process. 

If the above picture, the default flow reference is generated and here it was named as mulecraft-munit-api-flow. We can understand that this Api flow has an event source, and an event processer. The test case always calls the event processer. As it won’t care about the event source, we can use flow reference to call event processer. 

Set Event 

At the beginning of a Munit test, this processor can be used to indicate that the first message is sent to the flow for the purpose of testing. The set-event has the cloneOriginalEvent property. If set true, then it clones the event produced by the code and by default this property is false. 

Here a value is passed as “'requestPath':'/listener'” which will point to the main flow. We can pass values as queryParams also. 

 

 

  • Value: The content of the property 
  • Encoding: Defines the encoding of the message. This attribute is optional. 
  • Media Type: Defines the mime type of the message. This attribute is optional 

and coming to the attributes how this value should be supplied, always we should supply it in the expression like #[{}] including headers or queryParams. 

 

Assertion Connectors 

Assert equals: Used to do equal assertion. 

Assert that: Contains below matcher functions to do assertions, 

  • Core matchers 
  • String matchers 
  • Comparable matchers 
  • Iterable and map matchers 

Assert expression: Dataweave assertions library 

Assert equals 

Create a mule project, and set transform message like below picture, 

 

We have developed simple test case and have passed two attributes (through set event) namely Firstname and Lastname, 

 

and we are calling the flow then we are using assert equals to assert the response payload. 

 

 

Then go to test case flow, Right click it and click Run MUnit suite. Once the application starts it’s going to run the test cases once execution was done, we can see the green mark and overall coverage % also. 

 

That means the test case was a success and we can see the coverage for each component. 

Assert that 

 

In Assert we have a field called Expression. Here we need to provide what we would like to assert, I would like to assert payload.message which we used in main flow already, by default it gives a notNullValue(), but I wanted to equal assertion in assert for that component. 

 

Let’s see what functions are available from assert of that MUnit tools. The syntax is MunitTools:: , let’s go dataweave and remove notnullvalue() and click ctrl+space and you can see all the available for assert of that function. 

 

 

So, such many assertions can be done using assert that, but using assert equals we would be able to do one assertion that is equal. When we have an equal trigger forward with assert equals but when we want different type of matchers then go-ahead with assert that or assert expression. Now you see the different methods available in that. In-between that we should input the needed response. 

 

                        

Save it and run Munit test case. And it successfully succeeds like above (assert equals) 

Remember: At least, it covers 80% of the coverage for success which includes both positive and negative test cases. 

Assert Expression 

Similarly, we have Dataweave assertions library in that we use the functions wherever we want it. 

 

Save it and run Munit test case. And its successfully succeeded like above (assert equals and assert that) 

Assertions using dataweave file(.dwl) 

Since we follow a common standard of separating dataweave logic to dwl files, it is possible to do the same with assertions. 

Above we have written a dataweave logic in assert expression component then we take the dataweave logic into .dwl file and we refer to it here (assert expression). Yes, that can be possible. The advantage is, in the future if I wish to change this message (inside expression) then I need not alter the test case, and need not make any change, in the set event as I have supplied two query parameters. In future if I want to change these also, no need to hardcode that one. If we hard code everything in the test case then we need to alter it during every change, rather than supplying this value in .dwl file for better management. 

Let's see how we create a dwl file, 

Under src/test/resources always create a corresponding folder for each flow then we create folder like munitDemo. Inside that, create munit_demo_response.dwl file. Whatever the logic we must just paste it in that file. Now to refer the file into assertion, go back to assert expression give as below. 

 

 

In that, munitDemo is a folder name and munit-demo-response is a .dwl file which we created, rest are all the format of the standard. Save it and run Munit test case. 

 
In wrapping up this first part of our exploration into unit testing with MUnit, we've laid a solid foundation by delving into the basics. We've uncovered the significance of unit testing in ensuring the robustness of our code and explored various assertion connectors that serve as the backbone of verifying expected outcomes. 

Through practical demonstrations, we've seen how these assertion connectors operate in real-life scenarios, empowering us to validate our code's functionality effectively. As we journey deeper into MUnit, we'll continue to build upon these fundamentals, unlocking more advanced techniques and strategies to fortify our codebase. 

Stay tuned for the next installment, where we'll dive further into MUnit's capabilities, uncovering more powerful tools and methodologies to enhance our unit testing prowess. Remember, strong foundations pave the way for resilient and reliable software - and MUnit is our guiding light in this journey towards code excellence. 

 

Next part 

  • MUnit mocking processors 
  • MUnit verify event processor 
  • MUnit spy event processor 
Mulecraft Footer