play + SubEtha SMTP でメール送信のユニットテスト

PlayFrameworkで実装したメール送信の機能を、[SubEtha SMTP](https://github.com/voodoodyne/subethasmtp)を使ってテストコードを書いたメモ。

[wiser](https://github.com/voodoodyne/subethasmtp/blob/master/Wiser.md) がとっつきやすいので、これをRuleクラスで持つようにする方針。

## wiserを取り扱うRuleクラス作成

wiserが仮想SMTPサーバになる。
application.confから、ポート番号やホストを取得して、それをセットしてwiserを起動させる。

```java:MailTestRule.java

/**
 * 仮想SMTPサーバの起動・停止のRuleクラス.
 *
 */
public class MailTestRule extends ExternalResource {

    private Wiser wiser;

    private static Config config = ConfigFactory.load().getConfig("smtp");

    public static final String HOST = config.getString("host");

    public static final int PORT = config.getInt("port");

    public Wiser getWiser() {
        return this.wiser;
    }

    @Override
    protected void before() throws Throwable {
        wiser = new Wiser();
        wiser.setPort(PORT);
        wiser.setHostname(HOST);
        wiser.start();
    }

    @Override
    protected void after() {
        wiser.getMessages().clear();
        wiser.stop();
    }

```

## テストコードのサンプル

メール送信処理に、playアプリ起動が必要なら、アプリの起動・停止をするクラスを継承したものを作成する。

```java:SampleTest.java

import java.util.List;

import org.junit.ClassRule;
import org.junit.Test;
import org.subethamail.wiser.WiserMessage;

public class SampleTest {

   @ClassRule
   public static MailTestRule mailRule = new MailTestRule();

   @Test
   public void 送信される() {
       /* メール送信処理 */
       
       //送信されたメッセージを取得
       List<WiserMessage> messages = mailRule.getWiser().getMessages();

       assertThat(messages).isNotEmpty();            
   } 

　　@Test
    public void 宛先はxxx(){
        /* メール送信処理 */

        WiserMessage message = mailRule.getWiser().getMessages().get(0);

       assertThat(message.getEnvelopeReceiver()).isEqualTo("xxx@test.com");
    }

    @Test
    public void Ccはyyy() throws MessagingException, IOException {
       /* メール送信処理 */

       WiserMessage message = mailRule.getWiser().getMessages().get(0);

       assertThat(message.getMimeMessage().getHeader("Cc", ",")).contains("yyy@test.com");
    }

    @Test
    public void 件名はsubject() {
       /* メール送信処理 */

       WiserMessage message = mailRule.getWiser().getMessages().get(0);
   
      assertThat(message.getMimeMessage().getSubject()).isEqualTo("subject");
    }

   @Test
   public void 送信アドレスはaaa() {
       /* メール送信処理 */

       WiserMessage message = mailRule.getWiser().getMessages().get(0);

      assertThat(message.getEnvelopeSender()).isEqualTo("aaa@test.com"); 
   }

   @Test
   public void 本文はテンプレートをつくられたものに一致() {
         /* メール送信処理 */

       WiserMessage message = mailRule.getWiser().getMessages().get(0);   

       String expected = ...; //テンプレートから作成する処理
   
       assertThat(message.getMimeMessage().getContent().toString()).isEqualTo(expected);
   }
      

}
```

### 実際に送られるメール本文を確認したいとき

ダミーのSMTPサーバをたてて、それを使う形をとります。

[FakeSMTP](https://github.com/Nilhcem/FakeSMTP) は、eml形式でメッセージを残すので、試験の確証にもつかえそうです。javaがあれば動くので、すぐに試せるのも良い。

## 感想

メール送信もテストコードで確認できると楽。実際に送信されるわけではないので、誤送信の心配もない。
その気になれば本文の内容もテストできるし、積極的に使っていきたい。

### 参考サイト

http://qiita.com/tacchang001/items/79097b68cc9e22a1f401

http://www.bunkei-programmer.net/entry/2015/01/10/012647

http://qiita.com/rubytomato@github/items/b106ff8011bcad60bce2