Search code examples
emailgreenmail

simulate imaps server - Greenmail


i want to use Greenmail in order to simulate imaps server. i want to use the server for system tests, i want to run the greenmail server and deliver it emails and then get those emails from jobs that run on my app server. my question is what is the difference between GreenMail.start to deploying GreenMail as a webapp. does GreenMail.start deploy a server that listens and i can send it imaps request from different machines?

the reason i want to use GreenMail.start and not deploy GreenMail as a webapp is that i have to create an email account on the greenmail server every time the test runs that is because the tests will run on different machines in the same time so i don't want the same account for all machines.

my code:

import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

import java.io.IOException;
import java.security.Security;
import java.util.Properties;

import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.URLName;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import com.icegreen.greenmail.util.DummySSLSocketFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.icegreen.greenmail.user.GreenMailUser;
import com.icegreen.greenmail.user.UserException;
import com.icegreen.greenmail.util.GreenMail;
import com.icegreen.greenmail.util.ServerSetupTest;
import testIMAPS.MailSender;

public class GreenmailTest {
public static final String USER_PASSWORD = "abcdef123";
public static final String USER_NAME = "hascode";
public static final String EMAIL_USER_ADDRESS = "hascode@localhost";
public static final String EMAIL_TO = "[email protected]";
public static final String EMAIL_SUBJECT = "Test E-Mail";
public static final String EMAIL_TEXT = "This is a test e-mail.";
public static final String LOCALHOST = "127.0.0.1";
public static GreenMail mailServer;

@Before
public void setUp() {

    if (mailServer == null){
        Security.setProperty("ssl.SocketFactory.provider",
                DummySSLSocketFactory.class.getName());
        mailServer = new GreenMail(ServerSetupTest.IMAPS);
        mailServer.start();
    }
}

@After
public void tearDown() {
    mailServer.stop();
}

@Test
public void getMails() throws IOException, MessagingException,
        UserException, InterruptedException {
    // create user on mail server
    GreenMailUser user = mailServer.setUser(EMAIL_USER_ADDRESS, USER_NAME,
            USER_PASSWORD);

    // create an e-mail message using javax.mail ..
    MimeMessage message = new MimeMessage((Session) null);
    message.setFrom(new InternetAddress(EMAIL_TO));
    message.addRecipient(Message.RecipientType.TO, new InternetAddress(
            EMAIL_USER_ADDRESS));
    message.setSubject(EMAIL_SUBJECT);
    message.setText(EMAIL_TEXT);

    // use greenmail to store the message
    user.deliver(message);

    // fetch the e-mail via imaps using javax.mail .. 
    /*i want this code to be run on different machines to this greenmail server */
    Properties props = new Properties();
    String imapsProtocol = "imaps";
    props.setProperty("mail.store.protocol", imapsProtocol);

    props.setProperty("mail.imaps.port", String.valueOf(ServerSetupTest.IMAPS.getPort()));
    Session session = Session.getInstance(props);
    Store store = session.getStore(imapsProtocol);
    store.connect(LOCALHOST, USER_NAME, USER_PASSWORD);

    Folder folder = store.getFolder("INBOX");
    folder.open(Folder.READ_ONLY);
    Message[] messages = folder.getMessages();
    assertNotNull(messages);
    assertThat(1, equalTo(messages.length));
    assertEquals(EMAIL_SUBJECT, messages[0].getSubject());
    assertTrue(String.valueOf(messages[0].getContent())
            .contains(EMAIL_TEXT));
    assertEquals(EMAIL_TO, messages[0].getFrom()[0].toString());
}
}

when i deploy the greenmail webapp on tomcat i see as expected the port i defined is used. but when i use mailServer.start() i dont see the port is in used. why?

thanks :)


Solution

  • Yes, GreenMail.start starts a server using the provided ServerSetup configuration. GreenMail is accessible from other hosts depending on host setting (localhost vs. eg 0.0.0.0). You can do this regardless using GreenMail.start or when deploying GreenMail webapp (it is just a wrapper to throw it into an application server).

    You can preconfigure GreenMail Webapp with the users you require. See configuring GreenMail webapp for how to add users or configuring your IMAPS port via packaged web.xml .

    Regarding "seeing the port used": For mailServer.start(), you can access the IMAPS port via

    greenMail.getImaps().getPort()

    When running/deploying GreenMail as webapp, you preconfigure the port inside the web.xml . When GreenMail Webapp deploys, it logs the ports. I assume this is what you mean with "seeing the port used"?