2017-06-08 4 views
1

Le test suivant prend environ 5 secondes à exécuter en raison de l'inclusion de m.saveChanges().MimeMessage.saveChanges est vraiment lent

import org.junit.Before; 
import org.junit.Test;  
import javax.mail.MessagingException; 
import javax.mail.Session; 
import javax.mail.internet.MimeMessage; 
import java.io.IOException; 
import java.util.Properties; 
import static org.junit.Assert.assertEquals; 
import static org.mockito.Mockito.mock; 
import static org.mockito.Mockito.when; 

@Test 
public void test1() throws MessagingException, IOException { 
    Session s = Session.getDefaultInstance(new Properties()); 
    MimeMessage m = new MimeMessage(s); 
    m.setContent("<b>Hello</b>", "text/html; charset=utf-8"); 
    m.saveChanges(); 
    assertEquals(m.getContent(), "<b>Hello</b>"); 
    assertEquals(m.getContentType(), "text/html; charset=utf-8"); 
} 

J'ai aussi raillé la session avec Mockito mais il ne permet pas:

Session s = mock(Session.class); 
when(s.getProperties()).thenReturn(new Properties()); 

Quel est le problème ici? Que puis-je me moquer pour accélérer les choses?

Répondre

4

Fixez d'abord le most common mistakes people make when using JavaMail dans votre code.

DNS lookup peut nuire aux performances sur certaines machines. Pour le JDK, vous pouvez modifier les propriétés de sécurité pour mettre en cache la recherche DNS networkaddress.cache.ttl and networkaddress.cache.negative.ttl ou définir les propriétés système sun.net.inetaddr.ttl and sun.net.inetaddr.negative.ttl. Le comportement par défaut dans JDK 7 et versions ultérieures fait un bon travail de mise en cache.

De préférence, vous pouvez utiliser les propriétés de session pour éviter certaines de ces recherches.

  1. Définissez la propriété de session pour mail.smtp.localhost pour empêcher la recherche de nom dans la commande HELO.
  2. Définissez la propriété de session pour mail.from or mail.host (pas les versions de protocole) car cela empêchera la recherche de nom sur InternetAddress.getLocalAddress(Session). L'appel MimeMessage.saveChanges(), MimeMessage.updateHeaders(), MimeMessage.updateMessageID(), ou MimeMessage.setFrom() déclenchera cette méthode.
  3. Définissez la propriété de session pour mail.smtp.from pour empêcher la recherche sur la commande EHLO.
  4. Vous pouvez également définir la propriété système mail.mime.address.usecanonicalhostname sur false si votre code se base sur setFrom() mais que cela doit être géré par le point 2.
  5. Pour IMAP, vous pouvez essayer de définir mail.imap.sasl.usecanonicalhostname à false qui est la valeur par défaut.

Puisque vous n'êtes pas le transport d'un message, appliquer la règle n ° 2 en changeant votre code:

@Test 
public void test1() throws MessagingException, IOException { 
    Properties props = new Properties(); 
    props.put("mail.host", "localhost"); //Or use IP. 
    Session s = Session.getInstance(props); 
    MimeMessage m = new MimeMessage(s); 
    m.setContent("<b>Hello</b>", "text/html; charset=utf-8"); 
    m.saveChanges(); 
    assertEquals(m.getContent(), "<b>Hello</b>"); 
    assertEquals(m.getContentType(), "text/html; charset=utf-8"); 
} 

Si vous transportez un message puis combiner les règles # 1, # 2 et # 3 ce qui empêchera l'accès au système hôte pour une recherche de nom. Si vous souhaitez empêcher toutes les recherches DNS pendant un transport, vous devez utiliser des adresses IP.