Challenge Java EE !

Java EEを中心に趣味や仕事における開発メモを書いています。

MailSlurpを利用したメールのEnd-To-Endテスト

システム開発する上でメールの送受信テストは何かと面倒です。できればユニットテストに組み込んで人手のテストは避けたい所だと思います。

JavaでJUnitを使ってテストする場合、SubEtha SMTPのようなライブラリを使うと割と簡単にテストできます。この辺はWEB+DB PRESS Vol.102のJavaの新定石で特集されているので、詳しく知りたい方は手に取ってみてください。
gihyo.jp

プログラミング言語に縛られない良い方法はないのかなと思っていたところ、先日SparkPostのブログでMailSlurpというサービスが紹介されていました。

www.sparkpost.com

f:id:kikutaro777:20180218234316p:plain

End-to-endのメールテストを簡単にするサービスで、Web APIを使ってテスト用のinbox作成と受信確認ができます。

実際に試してみたら非常に簡単だったので紹介します。

アカウント作成後、API Keyを取得します。

f:id:kikutaro777:20180218230936p:plain

Web APIでinboxを作成します。

curl -X POST https://api.mailslurp.com/inboxes?apiKey=test

成功するとidと宛先のメールアドレスが返ってきます。

{
  "payload":{
    "id":"xxxxxx-xxxx-xxxx-xxxx-xxxx",
    "address":""xxxxxx-xxxx-xxxx-xxxx-xxxx@example.com"
  },
  "message":""
}

上記メアドにメールを送信後した後、idをURLのパスに含めてGETするとinboxで受信したメールを取得できます。

curl https://api.mailslurp.com/inboxes/xxxxxx-xxxx-xxxx-xxxx-xxxx?apiKey=test

レスポンスで返ってくるpayloadはinbox作成時と違って配列形式なので注意してください(気付かずJavaでJSON->Object変換にしばらくハマってました)

{
  "payload": [
    {
      "body": "xxxxx",
      "from": "xxx",
      "id": "xxxxxx-xxxx-xxxx-xxxx-xxxx",
      "received": "2018-02-18T14:11:02.688Z",
      "returnPath": "xxx@examle.com",
      "subject": "Hello",
      "to": [
        "string"
      ]
    }
  ],
    "message": ""
}

このようにWeb API経由でinboxを作成&受信確認できるので、言語に関わらず簡単に使えます。また、テスト用の宛先が発行されるので誤送信も防げます。

次のコードはJavaでテストした例です。メール送信はSendGrid&JavaMailを使っています。

/**
* MailSlurpを利用したメールのEnd-To-Endテスト
*
* @author kikuta
*/
public class MailSlurpTest {
private final static String MAILSLURP_API_KEY = "xxx";
private final static String SENDGRID_API_KEY = "xxx";
@Test
public void MailEndToEndTest() throws UnirestException, MessagingException, InterruptedException {
//MailSlurpにinboxを作成
HttpResponse<PostResponse> postRet = Unirest.post(" https://api.mailslurp.com/inboxes")
.queryString("apiKey", MAILSLURP_API_KEY)
.asObject(PostResponse.class);
//inboxの宛先
String testTo = postRet.getBody().getPayload().getAddress();
//JavaMailからSendGridのSMTPを利用してメール送信
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.sendgrid.net");
props.put("mail.smtp.port", 587);
props.put("mail.smtp.auth", true);
Session session = Session.getInstance(props, new Authenticator(){
@Override
protected PasswordAuthentication getPasswordAuthentication(){
return new PasswordAuthentication("apikey", SENDGRID_API_KEY);
}
});
session.setDebug(true);
Message msg = new MimeMessage(session);
msg.setSubject("subject");
msg.setContent("hello", "text/plain");
Address from = new InternetAddress("from@kikutaro.xyz");
msg.setFrom(from);
Address to = new InternetAddress(testTo);
msg.setRecipient(RecipientType.TO, to);
msg.setHeader("X-Mailer", "JavaMail");
//メール送信
Transport.send(msg);
//MailSlurpのinbox受信待ちのためにウェイト
Thread.sleep(20000);
//inboxで受信確認
HttpResponse<GetResponse> getRes = Unirest.get("https://api.mailslurp.com/inboxes/{id}")
.routeParam("id", postRet.getBody().getPayload().getId())
.queryString("apiKey", MAILSLURP_API_KEY)
.asObject(GetResponse.class);
getRes.getBody().getPayload().stream().forEach(p -> {
assertThat(p.getSubject(), is("subject"));
System.out.println(p.getBody());
});
}
}
view raw MailSlurpTest.java hosted with ❤ by GitHub

inbox作成にwaitが必要で、この時間をどのくらいに定めるか微妙なところですが、非常にお手軽です。実際に動くソースは以下に置きました。

github.com