This article will talk about writing Munit for the Batch Processing module in Mule 4. If you want to know more about Batch processing, you can refer to my previous blog, i.e., “Dealing with a large number of records by Batch Processing in Mule 4”.
What is Munit, and why do we need it?
Munit is a testing framework for Mule Applications. It is loaded with integration and unit test capabilities that can help you to improve your mule code quality. It also provides mocking capability to mock the external systems and behaviors easily.. In General, the developer basically uses it to do the unit testing and validation of the code’s success and error scenario, which confirms more stability.
Challenge for Munit in Batch Module:
- As discussed earlier in my previous blog about batch processing, batch processing is an Asynchronous process where the threads execute in parallel and asynchronously. But the Munit is a synchronous process for which it’s a challenge.
- Secondly, as we know, a batch does not affect the payload, and in the end, it gives us the batch job result, making it difficult to test the output or assert the output.
- Batch steps are scopes inside a batch, so they cannot be mocked or used for a verified call.
Solution For Munit test in Batch:
- The first component is SPY. You can use it to spy on your batch steps to check they are working as expected or not.
- Second, you can use the sleep component, which will let the main thread in Munit sleep for some time (You can define the time based on your no of records) meanwhile, the other threads in Batch can execute asynchronously and will be at the on complete stage by the time the main thread will wake up from sleep and start executing further, and we can assert the batch job results in validation part of Munit flow.
Use case by using SPY
- This is a simple batch job where my source is a database, and I am getting data as bulk and sending the data to salesforce by using Bulk API. For the failed record, I am using a queue to store it. This is a simple batch flow. Below is the Munit for this flow.
- This is the first step here. I have created a Munit Flow where I am using the spy component of Munit. In the processor section, I have selected the logger, which is in the on-complete step, and in the before call section, I have used two asset equals for spying. Here Thread Sleep component is used to stop the main thread for a defined time span/period.
- We can configure assert equals as below for spying success and failed records.
Similarly, you can also configure and check for the 2nd Batch step.
Use case by using Thread Sleep:
- This is the simple way to deal with Munit of the batch job. In this case, we can write Munit in a general way. We need to add a Munit Thread sleep component in the execution section of Munit.
- Below is my Batch flow, where the batch job has multiple complex batch steps, and each of them has different steps of transformation of data. So, in this case, instead of going for SPY, I am using Thread Sleep.
- Below is the picture of the Munit, where I have mocked all the external connectors and added the Thread sleep in the execution section. In asserting that component, I am validating the batch job result. So here, after calling the batch job using flow reference, the main thread will sleep for the given time, and meanwhile batch will complete the execution by other threads.
- Below is the configuration of Thread sleep and assert that. So we can define the time span and its time unit, and we can stop the main thread for that period of time. Within that time, batch threads will process and complete the execution.
- As we discussed earlier, the batch is asynchronous, so the above ways are preferable for writing the Munit for Batch.
- The preferable way and in case of complex batch steps you can go for thread sleep component.