Shiny Adventures

Shiny Adventures

of a software developer, @jhipster board member, @jugpaderborn organizer and father

Frederik Hahne
greenmail with jhipster bowtie

When it comes to testing JHipster provides a wide range of tests out of the box. Recently I found greenmail. Greenmail is a java library to test sending and receiving of emails from Java. This is quite useful during to development to test sending of emails (e.g. to check if all is configured correctly or if the responsiveness is fine in different email clients). Furthermore you can use greenmail in unit or integration tests which makes the setup of such tests easier as the sending of emails must not be mocked.

This post shows how to add greenmail to a jhipster application and what needs to be done to really send emails inside the MailServiceIT instead of mocking JavaMailSenderImpl.

First you need to add greenmail to your project. In this case add testImplementation 'com.icegreen:greenmail:1.5.10' to the build.gradle file.

Setup Greenmail

MailServiceIT.java

private static GreenMail greenMail; 1
@BeforeAll 2
public static void setupGreenmail() {
    greenMail = new GreenMail(ServerSetupTest.ALL); 3
    greenMail.withConfiguration(GreenMailConfiguration.aConfig().withDisabledAuthentication()); 4
    greenMail.start(); 5
}

@AfterEach
public void cleanup() throws FolderException {
    greenMail.purgeEmailFromAllMailboxes(); 6
}
  1. Create a static greenmail property
  2. Make sure greenmail is started only once for the whole test class
  3. Enable all protocols with port offset of 3000. See greenmail documentation for details
  4. Disable authentication such that users and mailboxes will be created on demand
  5. Start the greenmail server
  6. To make assertions easier we remove all received mails from all inboxes after each test

Adapt Configuration

As the smpt server is listening on port 3025 we need to tell the application to use this port.

src/test/resources/config/application.yml

  mail:
    host: localhost
    port: 3025

Remove all Mocks

MailServiceIT.java

@Spy 1
private JavaMailSenderImpl javaMailSender;

@Captor
private ArgumentCaptor<MimeMessage> messageCaptor; 2

@BeforeEach
public void setup() {
    MockitoAnnotations.initMocks(this); 3
    doNothing().when(javaMailSender).send(any(MimeMessage.class)); 4
    mailService = new MailService(jHipsterProperties, javaMailSender, messageSource, templateEngine);
}
  1. Replace with @Autowired
  2. The captor can be removed
  3. Can be removed
  4. Can be removed

Update Testcases

Each testcase needs to changed only a little. First we must make sure the email was really send to our greenmail service by waiting for an incoming email. Afterwards the received message can be fetched from greenmail and nearly all assertations on the MimeMessage can stay the same.

You have to remove a single test cases which tests the behaviour in case sending an email throws an exception, but I don’t see any significant value in that particular test case, especially as this is an integration test.

MailServiceIT.java

@Test
public void testSendEmail() throws Exception {
    mailService.sendEmail("john.doe@example.com", "testSubject", "testContent", false, false);

    assertThat(greenMail.waitForIncomingEmail(1500, 1)).isTrue(); 1

    MimeMessage[] messages = greenMail.getReceivedMessages();
    MimeMessage message = messages[0]; 2

    assertThat(message.getSubject()).isEqualTo("testSubject");
    assertThat(message.getAllRecipients()[0].toString()).isEqualTo("john.doe@example.com");
    assertThat(message.getFrom()[0].toString()).isEqualTo("test@localhost");
    assertThat(message.getContent()).isInstanceOf(String.class);
    assertThat(message.getContent().toString()).isEqualToIgnoringNewLines("testContent"); 3
    assertThat(message.getDataHandler().getContentType()).isEqualTo("text/plain; charset=UTF-8");
}
  1. Wait for incoming email
  2. Fetch the recived email to make assertations on it
  3. As either during sending or when processed by greenmail a linebreak is inserted we need change isEqualTo to isEqualToIgnoringNewLines

Using it during development

You can of course use greenmail during development, e.g. by starting the greenmail standalone service via docker compose. In that case you can connect an email client of your choice to the greenmail service and see the created emails for real.

The source code of the complete project is available on gitlab.

Recent posts

See more

About