Testing Greenmail without installing an SMTP server

I am trying to use Greenmail to unit test email functions on my localhost. The problem is that I don't have an SMTP server already installed and it feels like it's too killing to install. I expect there should be a free library that allows me to keep my zip code the same, but instead of actually sending email to an SMTP server, send it to my local machine so I can recover them (for the sake of unit testing).

I've used Greenmail once when developing with Grails and the experience is great. But I cannot find something like this for the Spring Framework. The Greenmail page says it has a mocking SMTP server bundled with JBoss. But I don't want to run JBoss as my web application is currently running on Tomcat.

Is there a similar service for Tomcat? Or is there a better way to send a test email to localhost where I can get the emails sent?

UPDATE

I tried using Ralph's method, but it still gives 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. Failed messages: 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

      

+3


source to share


5 answers


You can use Greenmail with any Java program, whether it uses Spring or not. You don't need any Spring specific stuff for it.

It starts some sort of mail processing 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>

      

This configuration will then configure Spring JavaMailSender to send its emails to GreenMail-Server, started and terminated by the test code.

+8


source


Edit (2017 Nov):

Dumbster link is dead, there is a fork on github https://github.com/kirviq/dumbster

---- Original message ----



Take a look at Dumbster - I use it for all my unit tests, as it allows me to assert against actual messages posted.

http://quintanasoft.com/dumbster/

+2


source


It seems like someone once suggested an integration like this: http://sourceforge.net/mailarchive/forum.php?thread_name=45DEB9E3.6090608%40consol.de&forum_name=greenmail-developers

I don't know if everything works ...

0


source


Doing something like this in a test spring

works fine for me:

ServerSetupTest.setPortOffset(<SOME_CUSTOM_PORT>);
testEmailServer = new GreenMail();
testEmailServer.start();

      

The main idea of ​​the class ServerSetupTest

is to create ServerSetup

a custom port offset for testing. See the docs for details .

0


source


Try to manually set the GreenMail server port as follows:

 @Before
public void startMailServer()
    throws Exception
{
    ServerSetup setup = new ServerSetup(3025,"localhost","smtp");
    greenMail = new GreenMail(setup);
    greenMail.start();
}

      

and then set your mail sender the same as above, note the protocol / host / port:

email.protocol=smtp
email.host=localhost
email.port=3025
email.username=to@localhost.com
email.password=to@localhost.com
email.auth=true
email.systemEmail=from@localhost.com

      

with bean config:

<bean id="javaMailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
    <property name="protocol" value="${email.protocol}" />
    <property name="host" value="${email.host}" />
    <property name="port" value="${email.port}" />
    <property name="username" value="${email.username}" />
    <property name="password" value="${email.password}" />
    <property name="javaMailProperties">
        <props>
            <prop key="mail.${email.protocol}.auth">${email.auth}</prop>
        </props>
    </property>
</bean>

      

0


source







All Articles