0
1

More than 3 years have passed since last update.

Play frameworkでテストコードを作成してみた。

Last updated at Posted at 2021-05-27

Play frameworkでのテストコード

Play frameworkでjunitを使ってテストコードを作成したのでメモ。

Playでプロジェクトを作成するとtest/controllersディレクトリ内にデフォルトでHomeControllerTest.javaが入っている。

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はそのテストメソッド終了と同時に破棄される。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1