Skip to main content

MuleSoft / Anypoint Studio Integration

Test email flows in MuleSoft Anypoint using MailSlurp's disposable email addresses. This guide covers both flow-based (HTTP Connectors + DataWeave + MUnit) and Java SDK approaches for automation QA developers.

Overview

MuleSoft developers can test email workflows using MailSlurp in two ways:

ApproachBest ForTools
Flow-BasedMuleSoft idioms, visual design, enterprise patternsHTTP Connector + DataWeave + MUnit
Java SDKDirect API access, plain JUnit testsMailSlurp Java Client + JUnit

Both approaches use real email addresses that can receive and send emails during automated tests.

Why MailSlurp for MuleSoft Testing?

  • Real Email Addresses - Create disposable inboxes on-demand via API
  • API-First - REST endpoints for all email operations (no IMAP/SMTP complexity)
  • OTP & Verification Flows - Wait for emails with timeouts, extract codes with regex
  • Zero Configuration - No mail servers to set up or maintain
  • MUnit Compatible - Mock external services while using real email delivery
  • DataWeave Ready - JSON responses work seamlessly with DataWeave transformations

Setup

Get an API Key

  1. Sign up for a free MailSlurp account
  2. Copy your API key from the dashboard
  3. Store it securely (environment variable or secrets manager)

Add Dependencies

Flow-Based (MUnit + HTTP Connector)

Add to pom.xml:

<dependencies>
<!-- Mule Runtime -->
<dependency>
<groupId>org.mule.connectors</groupId>
<artifactId>mule-http-connector</artifactId>
<version>1.10.3</version>
<classifier>mule-plugin</classifier>
</dependency>

<!-- DataWeave for transformations -->
<dependency>
<groupId>com.mulesoft.muleesb.modules</groupId>
<artifactId>mule-module-ee-core</artifactId>
<version>3.9.0</version>
</dependency>

<!-- MUnit for testing -->
<dependency>
<groupId>com.mulesoft.munit</groupId>
<artifactId>munit-runner</artifactId>
<version>3.3.1</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.mulesoft.munit</groupId>
<artifactId>munit-tools</artifactId>
<version>3.3.1</version>
<scope>test</scope>
</dependency>

<!-- Java Module for Selenium integration -->
<dependency>
<groupId>org.mule.modules</groupId>
<artifactId>mule-java-module</artifactId>
<version>1.2.13</version>
<classifier>mule-plugin</classifier>
</dependency>

<!-- Selenium WebDriver for browser automation -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.18.1</version>
</dependency>
</dependencies>

Java SDK (JUnit + MailSlurp Client)

Add to pom.xml:

<dependencies>
<!-- MailSlurp Java Client -->
<dependency>
<groupId>com.mailslurp</groupId>
<artifactId>mailslurp-client-java</artifactId>
<version>17.0.0</version>
</dependency>

<!-- JUnit for testing -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>

<!-- Selenium WebDriver -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.18.1</version>
</dependency>

<!-- SLF4J Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>2.0.5</version>
</dependency>
</dependencies>

Flow-Based Approach (MuleSoft Idioms)

The flow-based approach uses native MuleSoft patterns: visual flows, HTTP Connector, DataWeave transformations, and MUnit tests.

Architecture

┌─────────────────────────────────────────────────────────────────┐
│ otp-email-verification-flow │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌──────────────────┐ ┌──────────────┐ │
│ │ HTTP POST │───▶│ DataWeave │───▶│ Java Invoke │ │
│ │ /inboxes │ │ Extract inbox ID │ │ Browser │ │
│ └─────────────┘ │ & email address │ │ Signup │ │
│ └──────────────────┘ └──────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ ┌──────────────────┐ ┌──────────────┐ │
│ │ HTTP GET │◀───│ Wait for email │◀───│ │ │
│ │ /waitFor... │ │ │ │ │ │
│ └─────────────┘ └──────────────────┘ └──────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────┐ ┌──────────────┐ ┌─────────────┐ │
│ │ DataWeave │───▶│ Java Invoke │───▶│ Success │ │
│ │ Extract OTP │ │ Enter Code │ │ Response │ │
│ │ using regex │ │ & Login │ │ │ │
│ └──────────────────┘ └──────────────┘ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘

Configuration

Create src/main/resources/config.yaml:

mailslurp:
apiKey: "${MAILSLURP_API_KEY}"

test:
password: "test-password"

HTTP Request Configuration

Configure the MailSlurp API connection in your Mule flow XML:

<!-- HTTP Request Configuration for MailSlurp API -->
<http:request-config name="MailSlurp_HTTP_Config"
doc:name="HTTP Request configuration">
<http:request-connection host="api.mailslurp.com"
protocol="HTTPS"
port="443"
connectionIdleTimeout="60000" />
</http:request-config>

Step 1: Create Inbox

Use the HTTP Connector to create a real email inbox:

<flow name="otp-email-verification-flow">
<!-- Create MailSlurp Inbox -->
<http:request method="POST"
doc:name="Create Inbox"
config-ref="MailSlurp_HTTP_Config"
path="/inboxes">
<http:headers>
<![CDATA[#[{
"x-api-key": p('mailslurp.apiKey'),
"Content-Type": "application/json"
}]]]>
</http:headers>
</http:request>

<!-- Parse inbox response using DataWeave -->
<ee:transform doc:name="Extract Inbox Details">
<ee:message>
<ee:set-payload><![CDATA[%dw 2.0
output application/java
var inboxResponse = payload
---
{
inboxId: inboxResponse.id,
emailAddress: inboxResponse.emailAddress
}]]></ee:set-payload>
</ee:message>
<ee:variables>
<ee:set-variable variableName="inboxId"><![CDATA[%dw 2.0
output application/java
---
payload.id]]></ee:set-variable>
<ee:set-variable variableName="emailAddress"><![CDATA[%dw 2.0
output application/java
---
payload.emailAddress]]></ee:set-variable>
</ee:variables>
</ee:transform>

<logger level="INFO"
message='#["Created inbox: " ++ vars.emailAddress]' />
</flow>

API Response:

{
"id": "abc-123-def-456",
"emailAddress": "test-abc123@mailslurp.net",
"createdAt": "2024-01-15T10:30:00.000Z"
}

Step 2: Wait for Email

Use the waitForLatestEmail endpoint to wait for incoming emails:

<!-- Wait for confirmation email -->
<http:request method="GET"
doc:name="Wait For Email"
config-ref="MailSlurp_HTTP_Config"
path="/waitForLatestEmail">
<http:headers>
<![CDATA[#[{
"x-api-key": p('mailslurp.apiKey')
}]]]>
</http:headers>
<http:query-params>
<![CDATA[#[{
"inboxId": vars.inboxId,
"timeout": "60000",
"unreadOnly": "true"
}]]]>
</http:query-params>
</http:request>

API Response:

{
"id": "email-789",
"subject": "Please confirm your email address",
"from": "noreply@example.com",
"to": ["test-abc123@mailslurp.net"],
"body": "Your verification code is:\n\n123456",
"createdAt": "2024-01-15T10:31:00.000Z"
}

Step 3: Extract OTP with DataWeave

Use DataWeave regex to extract verification codes:

<ee:transform doc:name="Extract OTP Code">
<ee:message>
<ee:set-payload><![CDATA[%dw 2.0
output application/java
import * from dw::core::Strings

var emailBody = payload.body default ""
// Extract 6-digit code at end of line
var codeMatch = emailBody scan /([0-9]{6})$/

---
{
emailSubject: payload.subject,
emailBody: emailBody,
otpCode: if (sizeOf(codeMatch) > 0) codeMatch[0][1] else null
}]]></ee:set-payload>
</ee:message>
<ee:variables>
<ee:set-variable variableName="otpCode"><![CDATA[%dw 2.0
output application/java
import * from dw::core::Strings

var emailBody = payload.body default ""
var codeMatch = emailBody scan /([0-9]{6})$/

---
if (sizeOf(codeMatch) > 0) codeMatch[0][1] else null]]></ee:set-variable>
</ee:variables>
</ee:transform>

<logger level="INFO"
message='#["Extracted OTP code: " ++ (vars.otpCode default "NOT FOUND")]' />

<!-- Validate OTP was found -->
<choice doc:name="Validate OTP">
<when expression="#[vars.otpCode == null]">
<raise-error type="APP:OTP_NOT_FOUND"
description="Could not extract OTP code from email body" />
</when>
</choice>

DataWeave Regex Patterns:

PatternMatchesExample
([0-9]{6})$6-digit code at end of line"Your code: 123456"
code is:\s*(\d{6})Code after "code is:""Your code is: 456789"
verification:\s*([A-Z0-9]{8})8-char alphanumeric"Verification: ABC12345"

Step 4: Success Response

Return structured JSON with test results:

<ee:transform doc:name="Success Response">
<ee:message>
<ee:set-payload><![CDATA[%dw 2.0
output application/json
---
{
success: true,
message: "OTP Email Verification Test Passed",
details: {
emailAddress: vars.emailAddress,
inboxId: vars.inboxId,
otpCodeVerified: true
}
}]]></ee:set-payload>
</ee:message>
</ee:transform>

Error Handling

Add comprehensive error handling to your flow:

<error-handler>
<on-error-propagate enableNotifications="true"
logException="true">
<!-- Cleanup resources -->
<try doc:name="Try Close Browser">
<java:invoke instance="#[vars.browserHelper]"
class="com.smoketest.selenium.BrowserHelper"
method="closeBrowser()" />
<error-handler>
<on-error-continue enableNotifications="false"
logException="false" />
</error-handler>
</try>

<!-- Error response -->
<ee:transform doc:name="Error Response">
<ee:message>
<ee:set-payload><![CDATA[%dw 2.0
output application/json
---
{
success: false,
message: "OTP Email Verification Test Failed",
error: {
type: error.errorType.identifier,
description: error.description,
detailedDescription: error.detailedDescription
}
}]]></ee:set-payload>
</ee:message>
</ee:transform>
</on-error-propagate>
</error-handler>

MUnit Tests

Test your flow with MUnit:

<mule xmlns:munit="http://www.mulesoft.org/schema/mule/munit"
xmlns:munit-tools="http://www.mulesoft.org/schema/mule/munit-tools"
xmlns:http="http://www.mulesoft.org/schema/mule/http"
xmlns="http://www.mulesoft.org/schema/mule/core">

<munit:config name="otp-email-test-suite" />

<munit:test name="otp-email-verification-flow-test"
description="Test OTP email verification flow">
<munit:execution>
<!-- Execute the flow -->
<flow-ref name="otp-email-verification-flow" />
</munit:execution>

<munit:validation>
<!-- Assert success -->
<munit-tools:assert-that
expression="#[payload.success]"
is="#[MunitTools::equalTo(true)]" />

<!-- Assert OTP was verified -->
<munit-tools:assert-that
expression="#[payload.details.otpCodeVerified]"
is="#[MunitTools::equalTo(true)]" />

<!-- Assert email address is present -->
<munit-tools:assert-that
expression="#[payload.details.emailAddress]"
is="#[MunitTools::notNullValue()]" />

<!-- Assert inbox ID is present -->
<munit-tools:assert-that
expression="#[payload.details.inboxId]"
is="#[MunitTools::notNullValue()]" />
</munit:validation>
</munit:test>

</mule>

Running MUnit Tests

# Run all MUnit tests
mvn test

# Run specific test suite
mvn test -Dmunit.test=otp-email-test-suite

# Run specific test
mvn test -Dmunit.test=otp-email-test-suite#otp-email-verification-flow-test

# With verbose output
mvn test -X

Java SDK Approach

The Java SDK approach uses the MailSlurp Java client for direct API access with standard JUnit tests.

Configuration

Setup the MailSlurp client:

import com.mailslurp.clients.ApiClient;
import com.mailslurp.clients.Configuration;
import com.mailslurp.apis.InboxControllerApi;
import com.mailslurp.apis.WaitForControllerApi;

public class EmailTest {
private static final String MAILSLURP_API_KEY =
System.getenv("MAILSLURP_API_KEY");

private static ApiClient mailslurpClient;

@BeforeClass
public static void setup() {
// Configure MailSlurp client
mailslurpClient = Configuration.getDefaultApiClient();
mailslurpClient.setApiKey(MAILSLURP_API_KEY);
mailslurpClient.setConnectTimeout(60000);
}
}

Step 1: Create Inbox

import com.mailslurp.models.InboxDto;

@Test
public void test_createInbox() throws ApiException {
// Create a new inbox
InboxControllerApi inboxApi = new InboxControllerApi(mailslurpClient);
InboxDto inbox = inboxApi.createInboxWithDefaults().execute();

// Verify inbox was created
assertNotNull(inbox.getId());
assertTrue(inbox.getEmailAddress().contains("@mailslurp"));

System.out.println("Created inbox: " + inbox.getEmailAddress());
// Example: "test-abc123@mailslurp.net"
}

Step 2: Wait for Email

import com.mailslurp.models.Email;

@Test
public void test_waitForEmail() throws ApiException {
// Wait for email with timeout
WaitForControllerApi waitApi = new WaitForControllerApi(mailslurpClient);
Email email = waitApi.waitForLatestEmail()
.inboxId(inbox.getId())
.timeout(60000L)
.unreadOnly(true)
.execute();

// Verify email was received
assertNotNull(email.getId());
assertTrue(email.getSubject().contains("confirmation"));

System.out.println("Received email: " + email.getSubject());
}

Step 3: Extract OTP Code

import java.util.regex.Pattern;
import java.util.regex.Matcher;

@Test
public void test_extractOTP() {
// Extract 6-digit OTP from email body
String emailBody = email.getBody();
Pattern pattern = Pattern.compile("([0-9]{6})$", Pattern.MULTILINE);
Matcher matcher = pattern.matcher(emailBody);

assertTrue("Email body should contain 6-digit code", matcher.find());
String otpCode = matcher.group(1);

assertEquals("OTP should be 6 digits", 6, otpCode.length());
System.out.println("Extracted OTP: " + otpCode);
}

Complete JUnit Test Example

package com.smoketest.selenium;

import com.mailslurp.apis.InboxControllerApi;
import com.mailslurp.apis.WaitForControllerApi;
import com.mailslurp.clients.ApiClient;
import com.mailslurp.clients.ApiException;
import com.mailslurp.clients.Configuration;
import com.mailslurp.models.Email;
import com.mailslurp.models.InboxDto;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.FixMethodOrder;
import org.junit.runners.MethodSorters;

import static org.junit.Assert.*;

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class OtpEmailVerificationTest {

private static final String MAILSLURP_API_KEY =
System.getenv("MAILSLURP_API_KEY");
private static final Long TIMEOUT_MILLIS = 60000L;

private static ApiClient mailslurpClient;
private static InboxDto inbox;
private static Email email;
private static String confirmationCode;

@BeforeClass
public static void setup() {
assertNotNull("MAILSLURP_API_KEY must be set", MAILSLURP_API_KEY);

mailslurpClient = Configuration.getDefaultApiClient();
mailslurpClient.setApiKey(MAILSLURP_API_KEY);
mailslurpClient.setConnectTimeout(TIMEOUT_MILLIS.intValue());
}

@Test
public void test1_createInbox() throws ApiException {
System.out.println("Creating MailSlurp inbox...");

InboxControllerApi inboxApi = new InboxControllerApi(mailslurpClient);
inbox = inboxApi.createInboxWithDefaults().execute();

assertNotNull(inbox.getId());
assertTrue(inbox.getEmailAddress().contains("@mailslurp"));

System.out.println("Created inbox: " + inbox.getEmailAddress());
}

@Test
public void test2_receiveEmail() throws ApiException {
System.out.println("Waiting for confirmation email...");

WaitForControllerApi waitApi = new WaitForControllerApi(mailslurpClient);
email = waitApi.waitForLatestEmail()
.inboxId(inbox.getId())
.timeout(TIMEOUT_MILLIS)
.unreadOnly(true)
.execute();

assertTrue("Email subject should contain confirmation",
email.getSubject().contains("confirm"));

System.out.println("Received: " + email.getSubject());
}

@Test
public void test3_extractOTP() {
System.out.println("Extracting OTP code...");

Pattern p = Pattern.compile("([0-9]{6})$", Pattern.MULTILINE);
Matcher matcher = p.matcher(email.getBody());

assertTrue("Email should contain 6-digit code", matcher.find());
confirmationCode = matcher.group(1);

assertEquals("Code should be 6 digits", 6, confirmationCode.length());
System.out.println("Extracted OTP: " + confirmationCode);
}
}

Common Patterns

Pattern 1: Create Inbox & Send Email

<!-- Flow-Based -->
<flow name="send-email-flow">
<!-- Create inbox -->
<http:request method="POST" path="/inboxes"
config-ref="MailSlurp_HTTP_Config">
<http:headers>#[{"x-api-key": p('mailslurp.apiKey')}]</http:headers>
</http:request>

<!-- Extract email address -->
<ee:transform>
<ee:variables>
<ee:set-variable variableName="emailAddress">
<![CDATA[%dw 2.0
output application/java
---
payload.emailAddress]]>
</ee:set-variable>
</ee:variables>
</ee:transform>

<!-- Send email to inbox -->
<http:request method="POST" path="/send-email"
config-ref="MailSlurp_HTTP_Config">
<http:headers>#[{"x-api-key": p('mailslurp.apiKey')}]</http:headers>
<http:body><![CDATA[#[%dw 2.0
output application/json
---
{
to: [vars.emailAddress],
subject: "Test Email",
body: "Hello from MuleSoft!"
}]]]></http:body>
</http:request>
</flow>
// Java SDK
@Test
public void testSendEmail() throws ApiException {
// Create inbox
InboxControllerApi inboxApi = new InboxControllerApi(mailslurpClient);
InboxDto inbox = inboxApi.createInboxWithDefaults().execute();

// Send email
SendEmailOptions options = new SendEmailOptions()
.to(Arrays.asList(inbox.getEmailAddress()))
.subject("Test Email")
.body("Hello from MuleSoft!");

inboxApi.sendEmail(inbox.getId(), options).execute();

// Wait for email
WaitForControllerApi waitApi = new WaitForControllerApi(mailslurpClient);
Email email = waitApi.waitForLatestEmail()
.inboxId(inbox.getId())
.timeout(30000L)
.execute();

assertEquals("Test Email", email.getSubject());
}
<!-- DataWeave: Extract first URL -->
<ee:transform>
<ee:set-payload><![CDATA[%dw 2.0
output application/java
import * from dw::core::Strings

var emailBody = payload.body
var urlMatch = emailBody scan /(https?:\/\/[^\s]+)/

---
{
firstUrl: if (sizeOf(urlMatch) > 0) urlMatch[0][1] else null
}]]></ee:set-payload>
</ee:transform>
// Java: Extract first URL
Pattern p = Pattern.compile("(https?://[^\\s]+)");
Matcher matcher = p.matcher(email.getBody());

if (matcher.find()) {
String url = matcher.group(1);
System.out.println("Found URL: " + url);
}

Pattern 3: Wait for Multiple Emails

// Wait for multiple emails with unread-only filter
WaitForControllerApi waitApi = new WaitForControllerApi(mailslurpClient);

// Wait for first email
Email email1 = waitApi.waitForLatestEmail()
.inboxId(inbox.getId())
.timeout(60000L)
.unreadOnly(true)
.execute();

// Wait for second email (first one is now marked read)
Email email2 = waitApi.waitForLatestEmail()
.inboxId(inbox.getId())
.timeout(60000L)
.unreadOnly(true)
.execute();

// Get all emails
InboxControllerApi inboxApi = new InboxControllerApi(mailslurpClient);
PageEmailProjection emails = inboxApi.getEmails()
.inboxId(inbox.getId())
.execute();

System.out.println("Total emails: " + emails.getTotalElements());

Best Practices

1. Use Environment Variables for API Keys

Never hardcode API keys in your Mule flows or Java code.

<!-- config.yaml -->
mailslurp:
apiKey: "${MAILSLURP_API_KEY}"
# Set environment variable
export MAILSLURP_API_KEY=your_api_key_here
mvn test

2. Set Appropriate Timeouts

Email delivery is typically fast, but account for network delays:

<!-- MuleSoft: 60 second timeout -->
<http:query-params>
<![CDATA[#[{
"inboxId": vars.inboxId,
"timeout": "60000"
}]]]>
</http:query-params>
// Java: 60 second timeout
email = waitApi.waitForLatestEmail()
.inboxId(inbox.getId())
.timeout(60000L)
.execute();

3. Clean Up Resources

Always clean up browser sessions and resources in error handlers:

<error-handler>
<on-error-propagate>
<try>
<java:invoke method="closeBrowser()"
instance="#[vars.browserHelper]" />
<error-handler>
<on-error-continue />
</error-handler>
</try>
</on-error-propagate>
</error-handler>
@AfterClass
public static void cleanup() {
if (driver != null) {
driver.quit();
}
}

4. Use DataWeave for Complex Transformations

DataWeave is more powerful than Java regex for complex data extraction:

<ee:transform>
<ee:set-payload><![CDATA[%dw 2.0
output application/java
import * from dw::core::Strings

var body = payload.body
var codeMatch = body scan /verification code:\s*([0-9]{6})/
var linkMatch = body scan /(https:\/\/[^\s]+verify[^\s]+)/
var expiryMatch = body scan /expires in (\d+) (hours|minutes)/

---
{
verificationCode: if (sizeOf(codeMatch) > 0) codeMatch[0][1] else null,
verificationLink: if (sizeOf(linkMatch) > 0) linkMatch[0][1] else null,
expiryValue: if (sizeOf(expiryMatch) > 0) expiryMatch[0][1] else null,
expiryUnit: if (sizeOf(expiryMatch) > 0) expiryMatch[0][2] else null
}]]></ee:set-payload>
</ee:transform>

5. Use MUnit Mocking for Unit Tests

Mock external services while testing your flows:

<munit:test name="test-with-mocked-email">
<munit:behavior>
<!-- Mock the HTTP request to return test data -->
<munit-tools:mock-when processor="http:request">
<munit-tools:with-attributes>
<munit-tools:with-attribute attributeName="doc:name"
whereValue="Wait For Email" />
</munit-tools:with-attributes>
<munit-tools:then-return>
<munit-tools:payload value='#[{
"id": "test-email-123",
"subject": "Test Confirmation",
"body": "Your code: 123456"
}]' mediaType="application/json" />
</munit-tools:then-return>
</munit-tools:mock-when>
</munit:behavior>

<munit:execution>
<flow-ref name="otp-email-verification-flow" />
</munit:execution>

<munit:validation>
<munit-tools:assert-equals
actual="#[vars.otpCode]"
expected="123456" />
</munit:validation>
</munit:test>

Troubleshooting

API Key Not Set

Error:

401 Unauthorized

Solution: Ensure MAILSLURP_API_KEY environment variable is set:

export MAILSLURP_API_KEY=your_api_key_here
echo $MAILSLURP_API_KEY # Verify it's set

Email Not Received

Error:

Timeout waiting for email

Solutions:

  1. Check inbox ID is correct
System.out.println("Waiting for inbox: " + inbox.getId());
  1. Increase timeout
<http:query-params>
#[{ "timeout": "120000" }] <!-- 2 minutes -->
</http:query-params>
  1. Check email was actually sent
// List all emails in inbox
PageEmailProjection emails = inboxApi.getEmails()
.inboxId(inbox.getId())
.execute();
System.out.println("Total emails: " + emails.getTotalElements());

OTP Not Extracted

Error:

OTP code is null

Solutions:

  1. Print email body to debug
<logger level="INFO" message='#["Email body: " ++ payload.body]' />
  1. Test regex pattern
String emailBody = "Your verification code is:\n\n123456";
Pattern p = Pattern.compile("([0-9]{6})$", Pattern.MULTILINE);
Matcher m = p.matcher(emailBody);
if (m.find()) {
System.out.println("Found: " + m.group(1));
}
  1. Adjust regex for your email format

Common patterns:

  • End of line: ([0-9]{6})$
  • After text: code:\s*([0-9]{6})
  • Surrounded by spaces: \s([0-9]{6})\s
  • Any 6 digits: ([0-9]{6})

MUnit Tests Timeout

Error:

Flow execution timeout

Solution: Increase MUnit timeout in munit:test:

<munit:test name="otp-test" 
description="Test OTP flow"
timeOut="120000"> <!-- 2 minutes -->

Chrome Not Found (Selenium)

Error:

Cannot find Chrome binary

Solution: Install Chrome or specify ChromeDriver path:

System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
ChromeOptions options = new ChromeOptions();
options.setBinary("/path/to/chrome");

Example Projects

Flow-Based MUnit Example

Complete working example with visual Mule flows:

  • GitHub: mulesoft-anypoint-munit-otp-test
  • Features:
    • Visual flow design in Anypoint Studio
    • HTTP Connector for MailSlurp API
    • DataWeave transformations
    • MUnit test suite with assertions
    • Selenium browser automation via Java Module
git clone https://github.com/mailslurp/examples.git
cd examples/mulesoft-anypoint-munit-otp-test

# Set API key
export MAILSLURP_API_KEY=your_api_key_here

# Run tests
mvn test

# Open in Anypoint Studio
# File → Import → Anypoint Studio project from File System

Java SDK JUnit Example

Plain Java approach with MailSlurp client:

cd examples/mulesoft-anypoint-java-selenium-test

export MAILSLURP_API_KEY=your_api_key_here
mvn test

API Reference

Key Endpoints

EndpointMethodDescription
/inboxesPOSTCreate a new email inbox
/waitForLatestEmailGETWait for next email with timeout
/send-emailPOSTSend email from inbox
/inboxes/{inboxId}/emailsGETList all emails in inbox

Common Query Parameters

ParameterTypeDescriptionDefault
inboxIdUUIDTarget inbox IDRequired
timeoutLongWait timeout (ms)60000
unreadOnlyBooleanOnly return unread emailsfalse
sinceDateEmails after this datenull

Authentication

All API requests require an API key via the x-api-key header:

<http:headers>
<![CDATA[#[{ "x-api-key": p('mailslurp.apiKey') }]]]>
</http:headers>
ApiClient client = Configuration.getDefaultApiClient();
client.setApiKey("your-api-key-here");

DataWeave Quick Reference

Extract 6-Digit Code

%dw 2.0
import * from dw::core::Strings
var body = payload.body
var match = body scan /([0-9]{6})$/
---
if (sizeOf(match) > 0) match[0][1] else null

Extract URL

%dw 2.0
import * from dw::core::Strings
var body = payload.body
var match = body scan /(https?:\/\/[^\s]+)/
---
if (sizeOf(match) > 0) match[0][1] else null

Extract Multiple Values

%dw 2.0
import * from dw::core::Strings
var body = payload.body
---
{
code: (body scan /code:\s*([0-9]{6})/)[0][1],
link: (body scan /(https:\/\/verify[^\s]+)/)[0][1],
expiry: (body scan /expires:\s*(\d+)\s*(minutes|hours)/)[0][1]
}

Parse HTML Email

%dw 2.0
import * from dw::core::Strings
var html = payload.body
// Strip HTML tags
var plainText = html replace /<[^>]+>/g with ""
// Extract from plain text
var code = (plainText scan /([0-9]{6})/)[0][1]
---
{ otpCode: code }

Further Resources

Support

Need help? Contact us:


Last updated: February 2026