Java – test greenmail without installing an SMTP server
I'm trying to use greenmail to test the email function on my localhost The problem is that I don't have an SMTP server installed and think it's too much to install an SMTP server My expectation is that there should be a free library that allows me to keep my sending mail code the same, but not really send e-mail to the SMTP server and to my local machine so that I can retrieve them (for unit testing)
I used to use greenmail when I was developing with Grails, and the experience was great But I can't find anything similar to the spring framework In the greenmail page, it says there is a simulated SMTP server bundled with JBoss But I don't want to run JBoss because my web application is running on Tomcat
Does Tomcat have a similar service? Or is there a better way to send the test email to localhost, where can I retrieve the sent email?
to update:
I try to use Ralph's method, but it still produces the same exception:
[SimpleAsyncTaskExecutor-1] 2012-03-13 10:19:39,475 - ERROR: com.test.my.service.emailing.impl.EmailServiceImpl - Mail server connection Failed; nested exception is javax.mail.MessagingException: Could not connect to SMTP host: localhost,port: 3025; nested exception is: java.net.ConnectException: Connection refused: connect. Failed messages: javax.mail.MessagingException: Could not connect to SMTP host: localhost,port: 3025; nested exception is: java.net.ConnectException: Connection refused: connect org.springframework.mail.MailSendException: Mail server connection Failed; nested exception is javax.mail.MessagingException: Could not connect to SMTP host: localhost,port: 3025; nested exception is: java.net.ConnectException: Connection refused: connect; message exception details (1) are: Failed message 1: javax.mail.MessagingException: Could not connect to SMTP host: localhost,port: 3025; nested exception is: java.net.ConnectException: Connection refused: connect at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1391) at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:412) at javax.mail.Service.connect(Service.java:288) at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:389) at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:340) at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:336) at com.test.my.service.emailing.impl.EmailServiceImpl.test(EmailServiceImpl.java:388) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(UnkNown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(UnkNown Source) at java.lang.reflect.Method.invoke(UnkNown Source) at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309) at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) at org.springframework.aop.interceptor.AsyncExecutionInterceptor$1.call(AsyncExecutionInterceptor.java:80) at java.util.concurrent.FutureTask$Sync.innerRun(UnkNown Source) at java.util.concurrent.FutureTask.run(UnkNown Source) at java.lang.Thread.run(UnkNown Source) Caused by: java.net.ConnectException: Connection refused: connect at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.PlainSocketImpl.doConnect(UnkNown Source) at java.net.PlainSocketImpl.connectToAddress(UnkNown Source) at java.net.PlainSocketImpl.connect(UnkNown Source) at java.net.socksSocketImpl.connect(UnkNown Source) at java.net.socket.connect(UnkNown Source) at java.net.socket.connect(UnkNown Source) at com.sun.mail.util.socketFetcher.createSocket(SocketFetcher.java:233) at com.sun.mail.util.socketFetcher.getSocket(SocketFetcher.java:189) at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1359) ... 19 more
Solution
You can use greenmail with any Java program, whether it uses spring or not You don't need anything spring specific
It runs some kind of process mail server
import com.icegreen.greenmail.util.GreenMail; import com.icegreen.greenmail.util.GreenMailUtil; import com.icegreen.greenmail.util.ServerSetupTest; ... @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("ApplicationContext-Greenmail.xml") public class EmailServiceIntegrationTest { /** Class under test */ @Resource private EmailService emailService; private GreenMail greenMail; @Before public void startMailServer() { greenMail = new GreenMail(ServerSetupTest.SMTP); greenMail.start(); } @After public void stopMailServer() { greenMail.stop(); } @Test public void testPledgeReminder() throws InterruptedException,MessagingException { String mailText = "Hallo World"; String mailSubject = "Hallo"; String mailTo = "test@excaple.com"; /** when: sending a mail */ emailService.send(mailSubject,mailTo,mailText); assertTrue(greenMail.waitForIncomingEmail(5000,1)); Message[] messages = greenMail.getReceivedMessages(); assertEquals(1,messages.length); assertEquals(mailText,messages[0].getSubject()); String body = GreenMailUtil.getBody(messages[0]).replaceAll("=\r?\n",""); assertEquals(mailText,body); } }
Important: use port 3025
<bean id="javaMailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl"> <property name="javaMailProperties"> <util:properties> <prop key="mail.debug">false</prop> <prop key="mail.transport.protocol">smtp</prop> <prop key="mail.smtp.port">3025</prop> <prop key="mail.smtp.auth">true</prop> <prop key="mail.smtp.user">test@mail.extern</prop> <prop key="mail.smtp.host">localhost</prop> <prop key="mail.smtp.from">test@mail.extern</prop> </util:properties> </property> <property name="username" value="test"/> <property name="password" value="xxx"/> <property name="defaultEncoding" value="utf8" /> </bean>
Then, this configuration will configure the spring javamailsender to send its mail to the greenmail server started and completed by the test code