MuleSoft / Anypoint Studio Integration
Test email flows in MuleSoft Anypoint using MailSlurp with HTTP Connectors, DataWeave, MUnit, and Java SDK approaches for automation QA developers
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.
Quick Links
- Example Projects on GitHub
- Flow-Based Example (MUnit + DataWeave)
- Java SDK Example (JUnit + MailSlurp SDK)
- MailSlurp API Documentation
- Sign Up Free
Overview
MuleSoft developers can test email workflows using MailSlurp in two ways:
| Approach | Best For | Tools |
|---|---|---|
| Flow-Based | MuleSoft idioms, visual design, enterprise patterns | HTTP Connector + DataWeave + MUnit |
| Java SDK | Direct API access, plain JUnit tests | MailSlurp 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
- Sign up for a free MailSlurp account
- Copy your API key from the dashboard
- 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:
| Pattern | Matches | Example |
|---|---|---|
([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());
}
Pattern 2: Extract Links from Email
<!-- 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:
- Check inbox ID is correct
System.out.println("Waiting for inbox: " + inbox.getId());
- Increase timeout
<http:query-params>
#[{ "timeout": "120000" }] <!-- 2 minutes -->
</http:query-params>
- 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:
- Print email body to debug
<logger level="INFO" message='#["Email body: " ++ payload.body]' />
- 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));
}
- 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:
- GitHub: mulesoft-anypoint-java-selenium-test
- Features:
- Pure Java JUnit tests
- MailSlurp Java client library
- Selenium WebDriver integration
- Standard Maven project structure
cd examples/mulesoft-anypoint-java-selenium-test
export MAILSLURP_API_KEY=your_api_key_here
mvn test
API Reference
Key Endpoints
| Endpoint | Method | Description |
|---|---|---|
/inboxes |
POST | Create a new email inbox |
/waitForLatestEmail |
GET | Wait for next email with timeout |
/send-email |
POST | Send email from inbox |
/inboxes/{inboxId}/emails |
GET | List all emails in inbox |
Common Query Parameters
| Parameter | Type | Description | Default |
|---|---|---|---|
inboxId |
UUID | Target inbox ID | Required |
timeout |
Long | Wait timeout (ms) | 60000 |
unreadOnly |
Boolean | Only return unread emails | false |
since |
Date | Emails after this date | null |
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:
- Email: support@mailslurp.com
- Discord: Join our community
- GitHub Issues: mailslurp/examples
Last updated: February 2026