我有几个邮件收发器,我只想在@Async上打一下,并获得异步邮件的好处.
我唯一的问题是我不知道如何正确地测试它们,并且我想轻松地采用当前正在测试它们的方法,并在不对测试代码进行大量更改的情况下进行修改那是可能的.
例如,在测试类中,我将定义两个自动装配的bean.一个是邮件服务,它负责完成所有类似邮件的事务,另一个是JavaMailSender-但这是一个模拟.然后,我将模拟放到服务中,以便它实际上不会发送真实的电子邮件;)
@Autowired
Mailer mailer;
MockJavaMailSender mailSender;
@Before
public void setup() {
mailSender = new MockJavaMailSender();
mailer.setMailSender(mailSender);
}
这种方法非常有效,因为我可以问模拟问题或从中获取数据以确保邮件程序代码有效:
UserAccount userAccount = userAccountDao.find(1);
mailer.sendRetrievePassword(userAccount);
mailSender.assertTimesSent(1);
String text = mailSender.getMimeMessage().buildText();
// Do tests on text.
@Async的问题在于,尚未填充mailSender,因此测试将失败.
这是使用@Async的代码:
@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));
}
有没有很简单的方法来纠正这个问题?
解决方法:
好吧,看来这可能是解决方案.我真的不想返回mime消息,因为我的应用程序不需要…但是它可以工作:
@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);
}
这是使它通过的测试:
@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);
}