How to test @Async mailers in Spring 3.0.x?

I have several email programs that I just like to tickle @Async and take advantage of asynchronous mailing.

The only problem I am facing is that I don’t know how to test them correctly, and I would like to easily accept the method that I am testing and just changing, without making significant changes if possible.

For example, in a test class, I define two auto-programmable beans. One of them is the mailing list service, which is responsible for performing all transactions related to mail, and the other is with JavaMailSender, but this is the layout. Then I put the layout in the service so that it doesn't actually send real emails;)

@Autowired
Mailer mailer;

MockJavaMailSender mailSender;

@Before
public void setup() {
    mailSender = new MockJavaMailSender();
    mailer.setMailSender(mailSender);
}

This approach worked very well, because I can just ask my questions or get data from him to make sure my mail code works:

UserAccount userAccount = userAccountDao.find(1);

mailer.sendRetrievePassword(userAccount);

mailSender.assertTimesSent(1);
String text = mailSender.getMimeMessage().buildText();

// Do tests on text.

The problem with @Async is that mailSender is not populating yet, so the tests will fail.

here is the code that @Async uses:

@Async
@Override
public void sendRetrievePassword(UserAccount userAccount) {
    mailSender.send(new MimeMessageSupport(velocityEngine)
        .setTitle("Retrieve Password")
        .setTemplate("mail/retrievePassword.vm")
        .setToEmailAddress(userAccount.getEmailAddress())
        .addObject("userAccount", userAccount));
}

Is there an easy way to fix this?

+3
source share
1 answer

Well, it looks like this could be a solution. I really don't want to return a mime message since my application is not needed ... but it works:

@Async
@Override
public Future<MimeMessageSupport> sendRetrievePassword(UserAccount userAccount) {
    MimeMessageSupport mimeMessage = new MimeMessageSupport(velocityEngine)
        .setTitle("Retrieve Password")
        .setTemplate("mail/retrievePassword.vm")
        .setToEmailAddress(userAccount.getEmailAddress())
        .addObject("userAccount", userAccount);

    mailSender.send(mimeMessage);

    return new AsyncResult<MimeMessageSupport>(mimeMessage);
}

And here is the test so that it passes:

@Test
public void sendRetrievePassword() throws ExecutionException, InterruptedException {
    UserAccount userAccount = userAccountDao.find(1);

    Future<MimeMessageSupport> future = mailer.sendRetrievePassword(userAccount);

    String text = future.get().buildText();

    assertTrue(text.contains(userAccount.getEmailAddress()));
    assertTrue(text.contains(userAccount.getPassword()));

    mailSender.assertTimesSent(1);
}
+3
source

Source: https://habr.com/ru/post/1779653/


All Articles