Thomas De Rycke - 2013-06-05

Unitils Mail Module

This unitils module makes it easy to use a fake SMPT server during your tests.
In fact it is more than just a fake, its a spy, meaning that you can inspect the SMTP server to see wich
mails were sent to it by your application.

This module makes use of Wiser, a fake SMTP server https://code.google.com/p/subethasmtp/

Mail Module load artifact (maven)

    <dependency>
        <groupId>org.unitils.mail</groupId>
        <artifactId>unitils-mail</artifactId>
        <version>1.0.0</version>
    </dependency>

Mail Module project config

Please create unitils-local.properties, and add mail to unitils.modules. Code as following:

unitils.modules=inject,mail

unitils.module.mail.className = org.unitils.mail.MailModule
unitils.module.mail.runAfter=
unitils.module.mail.enabled=true

#org.unitils.mail.port = 25  #often blocked
org.unitils.mail.port = 65212

To start and use the fake smpt server put this in your test class.
This will start up the SMTP server before a test and cleans up, shuts it down after each test.

This has a performance cost but is nessacary to avoid any dependencies between tests

@TestSmtpServer
private SmtpServer simpleSmtpServer;

The SmtpServer comes with 2 methods that allow you to inspect its state:

/**
 * This method give you the amount of mails that you've sent to the SMTP server.
 * 
 */
int getReceivedEmailSize();

/**
 * This email sends you a list of all the mails you've sent to the fake SMTP server.
 * 
 */
List<SmtpMessage> getReceivedEmail() throws IOException, MessagingException;

So to use it in your test:

@RunWith(UnitilsJUnit4TestClassRunner.class)
public class MailModuleIntTest {

    @TestSmtpServer
    private SmtpServer simpleSmtpServer;

    @Test
    public void testSendEmail() {
        // Some action that makes your code send a mail
        // make sure that the same port as org.unitils.mail.port is used
        // CODE OMITTED

        assertEquals(1, simpleSmtpServer.getReceivedEmailSize());

    }
}

Remarks

Notice that this will work the best if your test & your SUT (system under test) are running in the same JVM.

If your application is deployed in some application server and is on the same machine as from where your test is launched, your test could still work.
However because it is no longer running in one thread, hence it is running in different JVM's you will probably have to introduce some Thread.sleep before you do some asserts.

If your application is deployed on a different machine as your from where you are launching your test, the test will fail.
The TestSmtpServer is only bound to a port on the machine from where you launch your test.

 

Last edit: Willemijn Wouters 2013-12-09