Keep on moving

あんまりまとまってないことを書きますよ

Scala(っていうかCommonsEmail)でMail送信をテストしたい

ScalaでEmail送りたいと思ってググったらCommons Email - Homeってのを
使うのがいいみたい。内部的にはJavaMailAPIってのを使ってるみたいですね。

Apache Commons Emailでメールを送信する

exception周りとか書いてないけどこんな感じで送信できます。

import org.apache.commons.mail.SimpleEmail

case class SendMailInfo(to: String, from: String, subject: String, msg: String)

class MyMailSender(sendHostName: String, charSet: String = "UTF-8") {

 def sendMail(mailInfo: SendMailInfo) {

   new SimpleEmail {
     setCharset(charSet)
     setHostName(sendHostName)
     setFrom(mailInfo.from)
     addTo(mailInfo.to)
     setSubject(mailInfo.subject)
     setMsg(mailInfo.msg)
   }.send
 }
}

テストの書き方

ユニットテストするときにはhttp://java.net/projects/mock-javamailを使うとモックを使ったテストが書けるみたい。*1
Commons EmailはJavaMail APIを使ってるのでこのライブラリ使えばmockを使ったテストが可能です。
今回は送信をチェックしたいのでこれでテストします。

import org.scalatest.FunSuite
import org.scalatest.BeforeAndAfter
import org.jvnet.mock_javamail.Mailbox

class MyMailSenderTest extends FunSuite with BeforeAndAfter {

  val HOST_NAME = "mail.example.com"
  var mailSender: MyMailSender = null

  before {
    mailSender = new MyMailSender(HOST_NAME)
    //clear Mock JavaMail box
    Mailbox.clearAll()
  }

  test("testSendInMockWay") {

    val subject = "Test2"
    val body = "Test Message2"
    mailSender.sendMail(SendMailInfo("to@example.com", "from@example.com", subject, body))

    // check JavaMail box
    val inbox = Mailbox.get("to@example.com")
    assert(inbox.isEmpty === false)
    assert(inbox.size() === 1)
    assert(subject === inbox.get(0).getSubject)
    assert(body === inbox.get(0).getContent)

 }
}

対象バージョン

  • Apache Commons Mail 1.2
  • mock-javamail 1.9

sbt

      libraryDependencies ++= Seq(
	"org.apache.commons" % "commons-email" % "1.2",

        // test
        "org.scalatest" %% "scalatest" % "1.8" % "test",
	"org.jvnet.mock-javamail" % "mock-javamail" % "1.9" % "test",

      )

*1:このライブラリJenkins作者のkohsukeさんが書いてるんですなぁ

Scalatra-scalatestでServletのテスト

ちなみにScalatra-ScalaTestを使って http://masahito.hatenablog.com/entries/2012/11/14 風のテストは以下のように書きます

package com.github.masahitojp.app

import org.scalatra.test.scalatest.ScalatraFunSuite


class MyScalatraServletSpec extends ScalatraFunSuite {
  // `MyScalatraServlet` is your app which extends ScalatraServlet
  addServlet(classOf[MyScalatraServlet], "/*")

  test("simple get") {
    get("/") {
      status should equal (200)
      body should include ("world!")
    }
  }
}

参考

servletのテスト

ServletなものへのテストはServletTesterを使って以下のように書くらしい。
ちなみにJUnit 4.10 + Jetty 7.Xでの書き方です。

http://docs.codehaus.org/display/JETTY/ServletTester

import org.junit.Before;
import org.eclipse.jetty.testing.HttpTester;
import org.eclipse.jetty.testing.ServletTester;
import org.junit.Test;

import static junit.framework.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

public class WebAppTest {
	private ServletTester tester;
	private HttpTester request;
	private HttpTester response;

	@Before
	public void setUp() throws Exception {
		this.tester = new ServletTester();
		this.tester.setContextPath("/");

		this.tester.addServlet(ApiWebAppServlet.class, "/api/*");
		this.tester.start();

		this.request = new HttpTester();
		this.response = new HttpTester();
		this.request.setMethod("GET");
		this.request.setHeader("Host", "tester");
		this.request.setVersion("HTTP/1.1");
	}
	@Test
	public void testHomepage() throws Exception {
		this.request.setURI("/api/node/");
		this.response.parse(tester.getResponses(request.generate()));
		assertTrue(this.response.getMethod() == null);
		assertEquals(200, this.response.getStatus());
		assertEquals("Hello World", this.response.getContent());
	}
}

はてなブログへ移転

アウトプットの集大成として本が出せたので、気分転換にはてなブログへ移行しました。
markdownとかはてな記法に対応してくれてるので、私の使い方としては問題ないかなー*1

*1: でもrestructredTextでも書きたいなー

Scalatra+scalatra-lift-jsonでJSON

ScalatraでJSONをrequest/responseで扱いたい場合にはscalatra-jsonを使うのが便利。

導入方法

build.sbtに以下のように追加します。
※バージョンは適宜変えてください。

libraryDependencies ++= Seq(
"org.scalatra" % "scalatra" % "2.1.1",
"org.scalatra" % "scalatra-lift-json" % "2.1.1"
)

使用例

↓のエントリを真似して書いてみた例

http://d.hatena.ne.jp/tototoshi/20120526/1338032893

感想

RESTful APIでpost/put/deleteなどでJSONを受ける際に、parsedBodyにpattern matchがすぐに使えるので
ソースコードの見通しが良くなるのが非常に嬉しいですね。

「JavaScriptテクニックバイブル ~効率的な開発に役立つ150の技」という本が出ます。

id:cimadai (@)さんにお誘いを受けまして執筆のお手伝いをさせていただきました。

JavaScriptテクニックバイブル ~効率的な開発に役立つ150の技

JavaScriptテクニックバイブル ~効率的な開発に役立つ150の技

この本ってどんな本?

Webアプリケーションを作るときの杖(not 魔法の杖) or 冒険の地図というのがコンセプトの一部です。

JavaScriptの知識はWebを検索すればすぐに見つかるようになりました。
しかし、見つかるものはすでに古くなっていたり、いい記事にたどり着くまでに時間がかかる事も多く、
こういうのをなんとかしたいというのがこの本の目的です。

O'Reilly Japan - Head First JavaScriptを読み終えた初心者から中上級者まで広く楽しんでいただけるような材料を取り揃えさせていただきました。
特にデバッグ&テストに多くのページを用意しております。

id:cimadaiさん、id:rokujyouhitoma(@) をはじめ, id:kiris60(@)さん、浜辺 将太 さん、藤木 祐介 さんら著者達が
選りすぐった読んですぐに役に立つ知識、イベントのような押さえておくべき知識やHTML5,
最新のライブラリの話など盛りだくさんの一冊になっております。

この本の使い方

アプリを開発するときに傍らにおいて使う事を想定しています。
是非他のJavaScriptの良著ともに開発を行っていただけると良いなと思っております。
本書中でも何冊か詳解したうちの何冊化を紹介しておきます。

JavaScript 第6版

JavaScript 第6版


テスト駆動JavaScript

テスト駆動JavaScript


Secrets of the Javascript Ninja

Secrets of the Javascript Ninja

まとめ

初めて読み通した技術書であるサイ本の日本語版の第6版が出る時期に本書を出せたのは、感慨深いものがあります。
本書は8月31日に発売予定です。是非一度手に取って読んでいただけると幸いです。