JUnit Email Testing Guide
Learn how to effectively test email functionality in Java applications using JUnit and Mail7. This comprehensive guide covers everything from basic setup to advanced testing scenarios with practical examples.
Setting Up JUnit Email Testing
To get started with email testing in JUnit, you'll need the following dependencies:
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.9.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.mail7</groupId>
<artifactId>mail7-java-sdk</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>javax.mail-api</artifactId>
<version>1.6.2</version>
</dependency>
</dependencies>
Basic Email Testing Setup
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import com.mail7.sdk.Mail7Client;
public class EmailTest {
private Mail7Client mail7Client;
private static final String API_KEY = System.getenv("MAIL7_API_KEY");
@BeforeEach
void setUp() {
mail7Client = new Mail7Client(API_KEY);
}
@Test
void testEmailDelivery() {
String testEmail = mail7Client.generateEmail();
EmailService emailService = new EmailService();
emailService.sendEmail(testEmail, "Test Subject", "Test Content");
List receivedEmails = mail7Client.getEmails(testEmail);
assertFalse(receivedEmails.isEmpty());
assertEquals("Test Subject", receivedEmails.get(0).getSubject());
}
}
Advanced Testing Scenarios
1. Testing Email Templates
@Test
void testEmailTemplate() {
String testEmail = mail7Client.generateEmail();
Map templateData = new HashMap<>();
templateData.put("username", "John");
templateData.put("resetLink", "https://example.com/reset");
emailService.sendTemplateEmail(testEmail, "password-reset", templateData);
List emails = mail7Client.getEmails(testEmail);
assertFalse(emails.isEmpty());
Email receivedEmail = emails.get(0);
assertTrue(receivedEmail.getBody().contains("John"));
assertTrue(receivedEmail.getBody().contains("https://example.com/reset"));
}
@Test
void testHtmlEmailTemplate() {
String testEmail = mail7Client.generateEmail();
String htmlTemplate = "Welcome {{username}}!
Click here to verify.
";
Map templateData = new HashMap<>();
templateData.put("username", "Alice");
templateData.put("link", "https://example.com/verify");
emailService.sendHtmlEmail(testEmail, "Welcome", htmlTemplate, templateData);
List emails = mail7Client.getEmails(testEmail);
assertFalse(emails.isEmpty());
Email receivedEmail = emails.get(0);
assertTrue(receivedEmail.isHtml());
assertTrue(receivedEmail.getBody().contains("Welcome Alice!"));
}
2. Testing Email Attachments
@Test
void testEmailWithAttachment() {
String testEmail = mail7Client.generateEmail();
File attachment = new File("test-data.pdf");
emailService.sendEmailWithAttachment(testEmail, "Document", "Please find attached.", attachment);
List emails = mail7Client.getEmails(testEmail);
assertFalse(emails.isEmpty());
Email receivedEmail = emails.get(0);
assertNotNull(receivedEmail.getAttachments());
assertEquals(1, receivedEmail.getAttachments().size());
assertEquals("test-data.pdf", receivedEmail.getAttachments().get(0).getFileName());
}
3. Testing Email Headers and Metadata
@Test
void testEmailHeaders() {
String testEmail = mail7Client.generateEmail();
Map headers = new HashMap<>();
headers.put("X-Priority", "1");
headers.put("X-Custom-Header", "test-value");
emailService.sendEmailWithHeaders(testEmail, "Test Headers", "Content", headers);
List emails = mail7Client.getEmails(testEmail);
Email receivedEmail = emails.get(0);
assertEquals("1", receivedEmail.getHeaders().get("X-Priority"));
assertEquals("test-value", receivedEmail.getHeaders().get("X-Custom-Header"));
}
Error Handling and Edge Cases
@Test
void testInvalidEmailAddress() {
String invalidEmail = "invalid.email@";
assertThrows(IllegalArgumentException.class, () -> {
emailService.sendEmail(invalidEmail, "Test", "Content");
});
}
@Test
void testLargeAttachment() {
String testEmail = mail7Client.generateEmail();
File largeFile = new File("large-file.zip"); // > 10MB
assertThrows(AttachmentSizeExceededException.class, () -> {
emailService.sendEmailWithAttachment(testEmail, "Large File", "Content", largeFile);
});
}
@Test
void testRetryMechanism() {
String testEmail = mail7Client.generateEmail();
// Simulate temporary network failure
when(emailClient.send()).thenThrow(new TemporaryNetworkException())
.thenReturn(true);
boolean sent = emailService.sendEmailWithRetry(testEmail, "Test Retry", "Content");
assertTrue(sent);
verify(emailClient, times(2)).send();
}
Best Practices and Testing Patterns
1. Using Test Categories
@Tag("email")
@Tag("integration")
class EmailIntegrationTest {
@Test
@Tag("smoke")
void basicEmailDelivery() {
// Basic smoke test
}
@Test
@Tag("performance")
void bulkEmailDelivery() {
// Performance test
}
}
2. Parameterized Tests
@ParameterizedTest
@ValueSource(strings = {
"text/plain",
"text/html",
"multipart/mixed"
})
void testDifferentContentTypes(String contentType) {
String testEmail = mail7Client.generateEmail();
emailService.sendEmailWithContentType(testEmail, "Test", "Content", contentType);
List emails = mail7Client.getEmails(testEmail);
assertEquals(contentType, emails.get(0).getContentType());
}
3. Test Lifecycle Management
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class EmailTestLifecycle {
private Mail7Client mail7Client;
private List testEmails = new ArrayList<>();
@BeforeAll
void setUp() {
mail7Client = new Mail7Client(API_KEY);
}
@BeforeEach
void createTestEmail() {
String testEmail = mail7Client.generateEmail();
testEmails.add(testEmail);
}
@AfterEach
void cleanupEmails() {
for (String email : testEmails) {
mail7Client.deleteEmails(email);
}
testEmails.clear();
}
}
Debugging and Troubleshooting
Common Issues and Solutions
- Email Not Received: Check spam folders, verify SMTP settings, and ensure proper delay in assertions
- Authentication Failures: Verify API keys and credentials are properly set in environment variables
- Timeout Issues: Adjust waiting periods for email delivery in test configurations
Logging and Monitoring
@Test
void testWithEnhancedLogging() {
String testEmail = mail7Client.generateEmail();
// Enable detailed logging for this test
Logger logger = LoggerFactory.getLogger(EmailTest.class);
logger.info("Starting email test with address: {}", testEmail);
try {
emailService.sendEmail(testEmail, "Test", "Content");
logger.info("Email sent successfully");
List emails = mail7Client.getEmails(testEmail);
logger.info("Retrieved {} emails", emails.size());
assertFalse(emails.isEmpty());
} catch (Exception e) {
logger.error("Test failed with exception", e);
throw e;
}
}
Integration with CI/CD
// Sample configuration for running email tests in CI/CD
@Tag("ci")
class CiEmailTest {
@Test
void ciEmailDeliveryTest() {
assumeTrue(System.getenv("CI") != null);
String testEmail = mail7Client.generateEmail();
emailService.sendEmail(testEmail, "CI Test", "Content");
await().atMost(30, TimeUnit.SECONDS)
.pollInterval(2, TimeUnit.SECONDS)
.until(() -> !mail7Client.getEmails(testEmail).isEmpty());
}
}
Test Categories
1. Functional Tests
- Email delivery verification
- Content validation
- Attachment handling
- Template processing
2. Error Handling Tests
- Invalid email addresses
- Server connection failures
- Template rendering errors
- Attachment size limits
3. Performance Tests
- Bulk email sending
- Response time measurement
- Concurrent email processing
- Resource utilization
Best Practices
Test Organization
- Use descriptive test names
- Group related tests
- Implement test lifecycle hooks
- Clean up test data
Test Data Management
- Use dynamic test emails
- Implement data cleanup
- Avoid hardcoded values
- Use test configurations
Assertions
- Use appropriate assertions
- Check multiple conditions
- Implement timeout assertions
- Validate email metadata
Common Testing Patterns
@Test
void testEmailPattern() {
// Test setup
String testEmail = mail7Client.generateEmail();
EmailTestBuilder builder = new EmailTestBuilder()
.withRecipient(testEmail)
.withSubject("Test Email")
.withContent("Test Content");
// Action
emailService.sendEmail(builder.build());
// Verification
await()
.atMost(10, TimeUnit.SECONDS)
.until(() -> {
List emails = mail7Client.getEmails(testEmail);
return !emails.isEmpty();
});
// Assertions
List emails = mail7Client.getEmails(testEmail);
Email received = emails.get(0);
assertAll(
() -> assertEquals("Test Email", received.getSubject()),
() -> assertEquals("Test Content", received.getContent()),
() -> assertNotNull(received.getMessageId())
);
}
Debugging Tips
- Logging: Enable detailed test logs
- Timeouts: Configure appropriate wait times
- Cleanup: Implement proper test cleanup
- Isolation: Ensure test independence
Start Testing with JUnit
Implement robust email testing in your Java applications with Mail7's testing infrastructure.