【JUnit】【Mail】 Email送信に関する単体試験について ~ SubEthaMail編 ~

■ はじめに

https://blogs.yahoo.co.jp/dk521123/36257589.html
の続き。
今回は、「SubEthaMail」を試す。

■ 設定

 * Gradleを使う

build.gradle

dependencies {
    // Use JUnit test framework
    testImplementation 'junit:junit:4.12'

    // SubEthaMail
    testCompile group: 'org.subethamail', name: 'subethasmtp', version: '3.1.7'

    // JavaMail(以下の「サンプル」を実行したい場合は、以下のコメントを外す)
    //compile group: 'com.sun.mail', name: 'javax.mail', version: '1.6.1'
}

■ サンプル

 * 例1:プレーンテキストメール
 * 例2:添付ファイル付きメール

例1:プレーンテキストメール

 * テスト対象として、以下の関連記事の「サンプル」の「EmailHandler.java」を使用
https://blogs.yahoo.co.jp/dk521123/36230453.html

EmailHandlerTest.java
import static org.junit.Assert.*;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;

import javax.mail.MessagingException;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.subethamail.wiser.Wiser;
import org.subethamail.wiser.WiserMessage;

import com.sample.mails.EmailHandler;

public class EmailHandlerTest {
  private static Wiser wiser;
  private final static String HOSTNAME = "localhost";
  private final static Integer PORT = 12500;

  @BeforeClass
  public static void setUpBeforeClass() throws Exception {
    // メールサーバを立てる
    wiser = new Wiser();
    wiser.setPort(PORT);
    wiser.setHostname(HOSTNAME);
    wiser.start();
  }

  @AfterClass
  public static void tearDownAfterClass() throws Exception {
    // メールサーバを落とす
    wiser.stop();
  }

  @Test
  public void test() throws MessagingException {
    final String expectTo = "to@sample.co.jp";
    final String expectFrom = "from@sample.co.jp";
    final String expectSubject = "タイトルです。";
    final String expectBody = "メール本文です。\\r\\n以上です。";

    EmailHandler target = new EmailHandler();
    target.setHost(HOSTNAME);
    target.setPort(PORT.toString());
    target.setToAddresses(Arrays.asList(expectTo));
    target.setFromAddress(expectFrom);
    target.setMailSubject(expectSubject);
    target.setMailBody(expectBody);
    target.send();

    // メール内容を検査
    List<WiserMessage> messages = wiser.getMessages();
    for (WiserMessage wiserMessage : messages) {
      assertEquals(expectFrom, wiserMessage.getEnvelopeSender());
      assertEquals(expectTo, wiserMessage.getEnvelopeReceiver());
      try {
        assertEquals(expectSubject, wiserMessage.getMimeMessage().getSubject());
      } catch (MessagingException ex) {
        fail("Error");
      }
      try {
        assertEquals(expectBody, wiserMessage.getMimeMessage().getContent());
      } catch (MessagingException | IOException ex) {
        fail("Error");
      }
    }
  }
}

例2:添付ファイル付きメール

 * テスト対象として、以下の関連記事の「サンプル」の「EmailHandler.java」を使用
https://blogs.yahoo.co.jp/dk521123/36230816.html

EmailHandlerTest.java
import static org.junit.Assert.*;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.List;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMultipart;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.subethamail.wiser.Wiser;
import org.subethamail.wiser.WiserMessage;

import com.sample.mails.EmailHandler;

public class EmailHandlerTest {

  private static Wiser wiser;
  private final static String HOSTNAME = "localhost";
  private final static Integer PORT = 12500;
  private final static int BUFFER_SIZE = 32768;

  @BeforeClass
  public static void setUpBeforeClass() throws Exception {
    // メールサーバを立てる
    wiser = new Wiser();
    wiser.setPort(PORT);
    wiser.setHostname(HOSTNAME);
    wiser.start();
  }

  @AfterClass
  public static void tearDownAfterClass() throws Exception {
    // メールサーバを落とす
    wiser.stop();
  }

  @Before
  public void setUp() throws Exception {
  }

  @After
  public void tearDown() throws Exception {
    if (wiser != null && wiser.getMessages() != null) {
      wiser.getMessages().clear();
    }
  }

  @Test
  public void test() {
    final String expectTo = "to@sample.co.jp";
    final String expectFrom = "from@sample.co.jp";
    final String expectSubject = "タイトルです。";
    final String expectBody = "メール本文です。\\r\\n以上です。";
    final String expectFileName = "sample.sql";
    final String expectFile = "C:\\temp\\sample.sql";
    try {
      EmailHandler target = new EmailHandler();
      target.setHost(HOSTNAME);
      target.setPort(PORT.toString());
      target.setToAddresses(Arrays.asList(expectTo));
      target.setFromAddress(expectFrom);
      target.setMailSubject(expectSubject);
      target.setMailBody(expectBody);
      target.setAttachmentFilePath(expectFile);
      target.send();
    } catch (Exception ex) {
      ex.printStackTrace();
      fail("Error : " + ex.getMessage());
    }

    // メール内容を検査
    List<WiserMessage> messages = wiser.getMessages();
    for (WiserMessage wiserMessage : messages) {
      // From
      assertEquals(expectFrom, wiserMessage.getEnvelopeSender());
      // To
      assertEquals(expectTo, wiserMessage.getEnvelopeReceiver());
      // Subject
      try {
        assertEquals(expectSubject, wiserMessage.getMimeMessage().getSubject());
      } catch (Exception ex) {
        fail("Error : " + ex.getMessage());
      }
      // Body
      try {
        MimeMultipart mimeMultipart = (MimeMultipart) wiserMessage.getMimeMessage().getContent();
        assertEquals(expectBody, mimeMultipart.getBodyPart(0).getContent());
      } catch (Exception ex) {
        fail("Error : " + ex.getMessage());
      }
      // Attachment File
      try {
        MimeMultipart mimeMultipart = (MimeMultipart) wiserMessage.getMimeMessage().getContent();
        // File Name
        assertEquals(expectFileName, mimeMultipart.getBodyPart(1).getFileName());
        // Content
        assertTrue(this.isSame(expectFile, mimeMultipart));
      } catch (Exception ex) {
        fail("Error : " + ex.getMessage());
      }
    }
  }

  private boolean isSame(String sourceFilePath, MimeMultipart destinationMimeMultipart)
      throws IOException, NoSuchAlgorithmException, MessagingException {
    File destinationCompareFile = File.createTempFile("attached", ".tmp");

    try (FileOutputStream outputStream = new FileOutputStream(destinationCompareFile);) {
      destinationMimeMultipart.getBodyPart(1).getDataHandler().writeTo(outputStream);
    }
    boolean isSame = this.isSame(new File(sourceFilePath), destinationCompareFile);
    destinationCompareFile.delete();
    return isSame;
  }

  private boolean isSame(File sourceFile, File destinationFile) throws IOException, NoSuchAlgorithmException {
    try (BufferedInputStream sourceInput = new BufferedInputStream(new FileInputStream(sourceFile));
        BufferedInputStream destinationInput = new BufferedInputStream(new FileInputStream(destinationFile));) {
      MessageDigest sourceMessageDigest = MessageDigest.getInstance("MD5");
      MessageDigest destinationMessageDigest = MessageDigest.getInstance("MD5");

      int next = 0;
      byte[] sourceBufferBytes = new byte[BUFFER_SIZE];
      byte[] destinationBufferBytes = new byte[BUFFER_SIZE];
      while (next != -1) {
        next = sourceInput.read(sourceBufferBytes);
        destinationInput.read(destinationBufferBytes);

        sourceMessageDigest.update(sourceBufferBytes);
        destinationMessageDigest.update(destinationBufferBytes);
      }
      return MessageDigest.isEqual(sourceMessageDigest.digest(), destinationMessageDigest.digest());
    }
  }
}

■ SubEthaMailあれこれ

ダミーサーバをクリアにしたい

上記の例2でも使用
wiser.getMessages().clear();


関連記事

Email送信に関する単体試験について ~ Dumbster編 ~

https://blogs.yahoo.co.jp/dk521123/36257589.html

Java で、 Email を送るには... [1] ~ JavaMail / テキストメール編 ~

https://blogs.yahoo.co.jp/dk521123/36230453.html

Java で、 Email を送るには... [2] ~ JavaMail / 添付ファイル付きメール編 ~

https://blogs.yahoo.co.jp/dk521123/36230816.html