javaemailtestingjakarta-mailgreenmail

Testing for sent email - Dumbster and greenmail not catching sent JavaMail


I'm trying to integrate Dumbster to test our JavaMail based notifier for outgoing emails. The emails get sent but in my test Dumbster does not pick them up. I'm not sure if I need additional configuration to make this work buton the dumbster homepage it says, it will listen automatically for mail sent through smtp on port 25.

This is our java mail setup:

<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
    <property name="host" value="smtp.somewhere.com" />
    <property name="port" value="25" />
    <property name="username" value="theUserName" />
    <property name="password" value="thePassword" />

    <property name="javaMailProperties">
        <props>
            <prop key="mail.smtp.auth">true</prop>
            <prop key="mail.smtp.starttls.enable">true</prop>
        </props>
    </property>
</bean>

Our Mailer class just injects the JavaMailer:

@Component
public class OurMailer {

    @Inject
    private MailSender mailSender;

    public void sendMail(String from, String to, String subject, String msg) {

        SimpleMailMessage message = new SimpleMailMessage();

        message.setFrom(from);
        message.setTo(to);
        message.setSubject(subject);
        message.setText(msg);
        mailSender.send(message);
    }

The test is quite straight forward as they demonstrate on their page:

@Inject
private OurMailer ourMailer;

@Test
public void ourMailer_should_send_mail() {
    SimpleSmtpServer server = SimpleSmtpServer.start();
    ourMailer.sendMail(FROM_EMAIL, TO_EMAIL, SUBJECT, MESSAGE);
    server.stop();
    Assert.assertTrue(server.getReceivedEmailSize() == 1);
}

As I said, the mail gets sent but the Assert fails.

Any ideas?

BTW: I also tried Greenmail but with the same result:

maven slightly different:

    <dependency>
        <groupId>com.icegreen</groupId>
        <artifactId>greenmail</artifactId>
        <version>1.3.1b</version>
        <exclusions>
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

The test

    GreenMail greenMail = new GreenMail(); //uses test ports by default
    greenMail.start();
    // send mail
    Assert.assertEquals("subject", greenMail.getReceivedMessages()[0].getSubject());
    greenMail.stop();

Solution

  • The test fails because the config says "Send the mail to the SMTP server smtp.somewhere.com" but you want to send it to the SimpleSmtpServer which runs on localhost

    Use a System property for the host parameter of the mailSender bean and set it to localhost when you run a test.

    That said, I suggest to split the test into two. The first test should just make sure that the method is called with the correct parameters. That way you will know that the code tries to send mails at the correct time; there is little point in testing SMTP authentication, your mail server, the mail infrastructure and the network in a unit test - all these are tested by their respective manufacturers.

    A second test should test just the method sendMail() method. Put that test into a test suite which can be run manually. What you want to know here is whether you correctly set up and use the MailSender API. Unless you change the code in the sendMail() method, you don't have to run this test at all.

    This will speed up your unit test and get rid of many unnecessary dependencies which can cause the test to fail even though your code works correctly.