Skip to content

Latest commit

 

History

History
107 lines (79 loc) · 3.58 KB

README.adoc

File metadata and controls

107 lines (79 loc) · 3.58 KB

Mock JavaMail

What is this?

Testing JavaMail applications is more difficult than necessary, because it involves a lot of setup outside the test program. Doing this correctly in a portable way so that anyone in your team can run the test is almost impossible.

Mock JavaMail comes to the rescue. This project takes advantage of pluggability in JavaMail, so that you can send/receive e-mails against a temporary in-memory "mailbox". For example, when this JAR is in your classpath, the following code that normally sends e-mail to me actually just sends the e-mail to an in-memory mailbox:

MimeMessage msg = new MimeMessage();
...
msg.setRecipients(TO,"first.last@example.com");
Transport.send(msg);

You can access this e-mail programatically like this:

List<Message> inbox = Mailbox.get("first.last@example.com");
assertEquals(inbox.size(),1); // was the e-mail really sent?

You can also directly add messages to this list to emulate e-mails in the inbox, instead of using the JavaMail API. Staging e-mails like this is useful for testing the server.

Similarly you can access these e-mails programatically by using JavaMail, just like you normally do:

Session session = ...;
Store store = session.getStore("pop3");  // imap would do, too

// connect to first.last@example.com mailbox
store.connect("example.com","first.last","anything");

Folder folder = store.getFolder("INBOX");
folder.open(Folder.READ_WRITE);
Message[] msgs = folder.getMessages();

This allows you to test both the sending side and receiving side. All you need to do is to drop the JAR in the classpath during the test.

Enforcing usage in tests

This library works thanks to the JavaMail API which allows to use different providers implementation to handle actual email sending.

To ensure it’s used in your tests, you need to define the following Java system properties:

mail.smtp.class

set to org.jvnet.mock_javamail.MockTransport

mail.pop3.class

set to org.jvnet.mock_javamail.MockStore

mail.imap.class

set to org.jvnet.mock_javamail.MockStore

This can be done either manually or via a configuration in your test runner.

Maven

For example, with Maven this can be done with the following configuration:

<project>
  […]
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <configuration>
          <systemPropertyVariables>
            <mail.smtp.class>org.jvnet.mock_javamail.MockTransport</mail.smtp.class>
            <mail.pop3.class>org.jvnet.mock_javamail.MockStore</mail.pop3.class>
            <mail.imap.class>org.jvnet.mock_javamail.MockStore</mail.imap.class>
          </systemPropertyVariables>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

Testing error handling behaviors

Mailbox can be marked as 'error' programatically, which causes all sending/receiving operations to fail. This can be used to test the error handling behavior of the application.

Mailbox inbox = Mailbox.get("first.last@example.com");
inbox.setError(true);

Documentation

If this project isn’t what you were looking for, see the following related projects: