Play frameworkでのテストコード
Play frameworkでjunitを使ってテストコードを作成したのでメモ。
Playでプロジェクトを作成するとtest/controllersディレクトリ内にデフォルトでHomeControllerTest.javaが入っている。
package controllers;
import org.junit.Test;
import play.Application;
import play.inject.guice.GuiceApplicationBuilder;
import play.mvc.Http;
import play.mvc.Result;
import play.test.WithApplication;
import static org.junit.Assert.assertEquals;
import static play.mvc.Http.Status.OK;
import static play.test.Helpers.GET;
import static play.test.Helpers.route;
public class HomeControllerTest extends WithApplication {
@Override
protected Application provideApplication() {
return new GuiceApplicationBuilder().build();
}
@Test
public void testIndex() {
Http.RequestBuilder request = new Http.RequestBuilder()
.method(GET)
.uri("/");
Result result = route(app, request);
assertEquals(OK, result.status());
}
}
テストメソッドの前には@Testのアノテーションが入り、テストメソッドは返り値なし。
ちなみにメソッド名は日本語でも良い(むしろ日本語の方がテスト内容がわかりやすかったりする)。
デフォルトで入っているテストのtestIndex()はインデックスページが表示されるかを確認している。
表示されたかどうかはassertEqualsメソッドでチェックしていて、assertEquals(予想される値, 実際の値)
で使う。
トップページが表示されるとステータスコードでOKが返されるのでそれで確認をしている。
他にもリダイレクトのチェックをしたいなら
assertEquals(SEE_OTHER, result.status())
リダイレクト先のチェックをしたいなら(リダイレクト先が/hogeの場合)
assertEquals("/hoge", result.redirectLocation().get())
などいろいろチェックできる。
投稿ができるかどうかのテストをしたい場合
@Test
public void 掲示板に投稿できるか() {
Http.RequestBuilder request = Helpers.fakeRequest()
.method(POST)
.bodyForm(ImmutableMap.of("title", "タイトルです", "message", "メッセージです。"))
.uri("/create");
int post_num = Post.find.all.size(); // 投稿前のデータベース上の投稿数を取得している
Result result = route(app, request);
assertEquals(post_num + 1, Post.find.all.size());
}
これは掲示板に投稿できるかどうかを確認するためのテスト。
投稿のチェックは投稿前と後でデータベース内の投稿数が1つ多くなる。
なので
投稿前の投稿数 + 1 = 投稿後の投稿数
がなり立てば投稿ができていることになる。
バリデーションがちゃんと動くかのテストがしたい場合
@Test
public void emailもpasswordも未入力の場合はバリデーションエラー() {
Http.RequestBuilder request = Helpers.fakeRequest()
.method(POST)
.bodyForm(ImmutableMap.of("email", "", "password", ""))
.uri("/logincheck");
request = CSRFTokenHelper.addCSRFToken(request);
Result result = route(app, request);
assertEquals(BAD_REQUEST, result.status());
}
これはログインフォームにemailとパスワードが空の状態で送信したらバリデーションに引っかかりBad Requestを返す処理をテストしている。
CSRFTokenHelper.addCSRFToken(request);
でCSRFトークンをリクエストに追加しているが、これが無いと
failed: java.lang.RuntimeException: No CSRF token was generated for this request! Is the CSRF filter installed?
というエラーが出て怒られる。
基本的にPlay frameworkでは自動でCSRFトークンが生成されるが、バリデーションに引っかかるような場合はされないのかもしれない。
ログインしているかどうかで処理が変わるものをテストする場合
例えばログイン中にログイン画面(IDやパスワードを入力するためのページ)にアクセスできたらおかしいので、もしユーザーがログイン画面のURIにアクセスしたらリダイレクトさせる必要がある。
@Test
public void ログイン中はloginページを表示できない() {
Http.RequestBuilder request = Helpers.fakeRequest()
.method(GET)
.uri("/login");
request.session("login", User.finder.byId(1).getEmail()); // IDが1のユーザーをログインさせる
Result result = route(app, request);
assertEquals(SEE_OTHER, result.status()); // リダイレクトするかチェック
assertEquals("/", result.redirectLocation().get());
}
sessionメソッドを使用してログイン状態を作り出した。
使い方はsession("session名", セッションに保存させたい値)
テストメソッド内で保存したsessionはそのテストメソッド終了と同時に破棄される。