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
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
}
- Create a static greenmail property
- Make sure greenmail is started only once for the whole test class
- Enable all protocols with port offset of 3000. See greenmail documentation for details
- Disable authentication such that users and mailboxes will be created on demand
- Start the greenmail server
- 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
@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);
}
- Replace with
@Autowired
- The captor can be removed
- Can be removed
- 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");
}
- Wait for incoming email
- Fetch the recived email to make assertations on it
- As either during sending or when processed by greenmail a linebreak is inserted we need change
isEqualTo
toisEqualToIgnoringNewLines
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.