JUnit Email Testing Guide

Updated February 14, 2024

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.