DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workkloads.

Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Any Version of the Test Pyramid Is a Misconception – Don’t Use Anyone
  • Error Handling Inside Kumologica Subflow
  • Mock API KIT: Router and Write Munit Test Cases for Different Error Types
  • Test-Case Reviews in Scrum-Teams

Trending

  • Chaos Engineering for Microservices
  • Zero Trust for AWS NLBs: Why It Matters and How to Do It
  • Why Documentation Matters More Than You Think
  • A Modern Stack for Building Scalable Systems
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. Testing, Tools, and Frameworks
  4. MUnit and Mule Runtime: Part II

MUnit and Mule Runtime: Part II

MUnit test cases — both unit and functional — can pretty easily be used to test various flows, whether they're main flows, decision flows, or sub-flows.

By 
Harish Kumar user avatar
Harish Kumar
·
Feb. 07, 17 · Opinion
Likes (3)
Comment
Save
Tweet
Share
12.2K Views

Join the DZone community and get the full member experience.

Join For Free

This blog is the continuation of my previous blog about MUnit, so if you have not read it yet, I would highly recommend that you go through it before continuing. Alternatively, you can watch the video tutorial on YouTube.

Let’s get going. If you remember last time, we created a Mule project with four flows: a main flow, a decision flow, and two sub-flows. 

So, we will be writing a unit test case for the decision flow and a functional test case for the decision flow and sub-flows. With this, we will be able to cover both unit test and function test cases.

Unit Test Case

As I explained in the last blog, while doing unit testing, we try to isolate the part of code that is under test as much as possible. If it depends on some other part of code, we try to mock it with replacement dummy functions. It's the same case with Mule flows. When we write unit test cases for a flow and the flow under test is calling other flows, we try to mock the flows and test the single flow in its entirety.

When doing unit tests, you isolate your flow from third-party systems and other flows and trust they work as expected. In turn, you must test each third-party system or flow with its own specific test.

If the flow takes different actions based on different values of the payload or on the contents of a variable, we should design more that one test for that flow.

One important point to remember is in MUnit you don’t mock or verify flow-ref, we mock or verify the flow andsub-flow.

MUnit Initialization

Any MUnit test case starts with the initialization of MUnit and importing of the XML config file where you have written your flows that you want to test.

<munit:config name="munit"doc:name="MUnit configuration"/>
  <spring:beans>    
  <spring:importresource="classpath:munit-demo.xml"/>
</spring:beans>

Unit Test Case 1 (sub-flow-test-suite.xml)

Since our smallest part of the code are the sub-flows, we will write the unit tests for them first.

 Image title

<?xml version="1.0" encoding="UTF-8"?>

<mule xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:munit="http://www.mulesoft.org/schema/mule/munit" xmlns:spring="http://www.springframework.org/schema/beans"
xmlns:core="http://www.mulesoft.org/schema/mule/core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.mulesoft.org/schema/mule/munit http://www.mulesoft.org/schema/mule/munit/current/mule-munit.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd">

<munit:config name="munit" doc:name="MUnit configuration" />

<spring:beans>
<spring:import resource="classpath:munit-demo.xml" />
</spring:beans>



<munit:test name="sub-flow-test-suite-decision1SubFlowTest"
description="Test">
<flow-ref name="decision1SubFlow" doc:name="Flow-ref to decision1SubFlow" />
<munit:assert-on-equals expectedValue="#['decision2']"
actualValue="#[flowVars.decisionVariable]" doc:name="Assert Equals"
message="Sorry did not got expected Value i.e. decision1 insted we got #[flowVars.decisionVariable]" />
</munit:test>
</mule>

Let’s understand what’s going on here. Since the task of these sub-flows is just to set the flow variable named decisionVariable, we are going to simply make a flow reference to these two flows and use the munit:assert-on-equals function to check the value of flow variable to be equal to the expected value.

Unit Test Case 2 (decision-flow-test-suite.xml)

In our flows, the decision flow is the place where we decide (based on the payload sent by the main flow) which sub-flow to go, using the choice router of Mule. Those sub-flows set the decision variable into flow vars. We will be writing two test cases for decision flow (actually four) where first we will test that the correct sub-flow is being invoked when we send the proper payload. In a separate test case, we will test if the correct flow variable is being set by sub-flows. There are four possibilities (for example, invocation of two sub-flows and return of two different values of flow variables) — that is the reason I said four test cases.

Testing Invocation of Sub-Flows

Image title

<?xml version="1.0" encoding="UTF-8"?>

<mule xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mock="http://www.mulesoft.org/schema/mule/mock" xmlns:munit="http://www.mulesoft.org/schema/mule/munit"
xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.mulesoft.org/schema/mule/mock http://www.mulesoft.org/schema/mule/mock/current/mule-mock.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/munit http://www.mulesoft.org/schema/mule/munit/current/mule-munit.xsd">
<munit:config name="munit" doc:name="MUnit configuration" />
<spring:beans>
<spring:import resource="classpath:munit-demo.xml" />
</spring:beans>


<munit:test name="decision-flow-test-mock-call-1-suiteTest"
description="MUnit Test">
<set-payload doc:name="Set Payload" value="#['value1']" />
<flow-ref name="decisionFlow" doc:name="decisionFlow" />
<mock:verify-call doc:name="Verify Call"
messageProcessor="mule:sub-flow" times="1">
            <mock:with-attributes>
                <mock:with-attribute name="name" whereValue="#[matchContains('decision1SubFlow')]"/>
            </mock:with-attributes>
</mock:verify-call>
</munit:test>


<munit:test name="decision-flow-flow-var-1-suiteTest"
description="MUnit Test">
<set-payload doc:name="Set Payload" value="#['value1']" />
<flow-ref name="decisionFlow" doc:name="decisionFlow" />
<munit:assert-on-equals expectedValue="#['decision1']"
actualValue="#[flowVars.decisionVariable]" doc:name="Assert Equals"
message="Sorry did not got expected Value i.e. decision1 insted we got #[flowVars.decisionVariable]" />

</munit:test>

</mule>

In this test case, we are setting the payload value before calling the decisionFlow using the flow-ref. Then, by using the mock:verify-call, we verify that the correct sub-flow is being invoked.

In verify-call, an important thing to notice is that I have used matchContains, a matcher of MUnit.

When mocking or verifying a sub-flow and using the name attribute, always use the MUnit matcher matchContains.

This is not needed when verifying or mocking flows — only for sub-flows. I have not given the XML part of the send test. I'll leave it up to you to try to implement it.

Testing Flow Variable Value

<munit:test name="decision-flow-flow-var-1-suiteTest"
description="MUnit Test">
<set-payload doc:name="Set Payload" value="#['value1']" />
<flow-ref name="decisionFlow" doc:name="decisionFlow" />
<munit:assert-on-equals expectedValue="#['decision1']"
actualValue="#[flowVars.decisionVariable]" doc:name="Assert Equals"
message="Sorry did not got expected Value i.e. decision1 insted we got #[flowVars.decisionVariable]" />

</munit:test>

This test case is very similar to the test case for sub-flows. The only difference is that we are setting the payload value, and instead of calling sub-flow, we make a call to decision flow.

The Assert part of decision variable is completely the same. We could have easily merged this test case with the invocation test case, but it’s always a good idea to separate your test cases so that they have only one responsibility: testing only one function.

Again, I left the second test case implementation for you to try.

I will end here. In the next (and last) part of this blog series, we will see how to unit test our main flow. Testing the main flow is going to be tricky because we are required to mock the flow reference calls. We will also see how to write functional tests (end-to-end testing of our flow).

unit test Flow (web browser) Test case

Published at DZone with permission of Harish Kumar, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Any Version of the Test Pyramid Is a Misconception – Don’t Use Anyone
  • Error Handling Inside Kumologica Subflow
  • Mock API KIT: Router and Write Munit Test Cases for Different Error Types
  • Test-Case Reviews in Scrum-Teams

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!