2010-12-10 62 views
3

J'ai plusieurs mailers que je voudrais juste slapper @ Async et profiter des avantages de l'envoi asynchrone. Le seul problème que j'ai est que je ne sais pas comment les tester correctement, et je voudrais facilement prendre la méthode que je suis en train de tester avec eux et juste le modifier sans apporter de changements massifs à le code de test si c'est possible. Par exemple, dans une classe de test, je vais définir deux beans autowired. L'un est le service d'expédition, qui est chargé de faire toutes les transactions de type courrier, et l'autre est le JavaMailSender - mais c'est un simulacre. Je place ensuite la maquette dans le service afin qu'il n'envoie pas réellement les vrais emails;)Comment tester correctement les expéditeurs @Async dans Spring 3.0.x?

@Autowired 
Mailer mailer; 

MockJavaMailSender mailSender; 

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

Cette approche a très bien fonctionné, parce que je peux poser mes questions fausses ou obtenir des données à partir de assurez-vous que mon code mailer fonctionne:

UserAccount userAccount = userAccountDao.find(1); 

mailer.sendRetrievePassword(userAccount); 

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

// Do tests on text. 

Le problème avec @Async est que MailSender ne sera pas encore rempli, de sorte que les essais échoueront.

est le code ici qui utilise @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)); 
} 

est-il un moyen vraiment facile à corriger?

+1

Où sont vous utilisez '@ Async' dans cet exemple? – skaffman

+0

@skaffman: Je l'afficherai ci-dessus – egervari

Répondre

3

Eh bien, il semble que cela pourrait être la solution. Je ne veux pas vraiment renvoyer le message mime que ma demande n'a pas besoin de ... mais il fonctionne:

@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); 
} 

Et voici le test pour le faire passer:

@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); 
}