You can run smtp4dev in automated Java tests using Testcontainers. This involves pulling the rnwood/smtp4dev:v3 image, exposing ports 80 (Web), 25 (SMTP), and 143 (IMAP), and configuring the ServerOptions__Urls environment variable to ensure the web server is accessible. You can then verify captured emails by querying the /api/messages endpoint.
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.wait.strategy.Wait;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.AfterEach;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import java.util.Properties;
public class SmtpTestcontainersTest {
private GenericContainer<?> smtp4dev;
private HttpClient httpClient;
private String baseUrl;
private int smtpPort;
@BeforeEach
void setUp() {
smtp4dev = new GenericContainer<>("rnwood/smtp4dev:v3")
.withExposedPorts(80, 25, 143)
.withEnv("ServerOptions__Urls", "http://*:80")
.waitingFor(Wait.forHttp("/").forPort(80));
smtp4dev.start();
int webPort = smtp4dev.getMappedPort(80);
smtpPort = smtp4dev.getMappedPort(25);
baseUrl = "http://localhost:" + webPort;
httpClient = HttpClient.newHttpClient();
}
@Test
void testEmailCapture() throws Exception {
// Send email via SMTP
Properties props = new Properties();
props.put("mail.smtp.host", "localhost");
props.put("mail.smtp.port", smtpPort);
Session session = Session.getDefaultInstance(props);
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress("test@example.com"));
message.addRecipient(Message.RecipientType.TO, new InternetAddress("recipient@example.com"));
message.setSubject("Test Subject");
message.setText("Test Body");
Transport.send(message);
// Wait and check API
Thread.sleep(1000);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(baseUrl + "/api/messages"))
.build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
assert response.body().contains("Test Subject");
}
@AfterEach
void tearDown() {
if (smtp4dev != null) {
smtp4dev.stop();
}
}
}