The HIRO Says

If you smell what The HIRO is cooking!!!

【slim3】画面遷移のための”Controller”−(3)UTの実施方法

前回slim3 の画面遷移制御用コンポーネントである
”Controller”の実装方法をまとめました。
今回は、この Controller の UT の実施方法を見てみます。


1.テストクラスの概要

Controller のテストクラスは、Controller クラスと一緒に Ant で自動生成されます。
テストクラスのポイントは、以下の2点です。
(1)org.slim3.tester.ControllerTestCase を継承すること。
(2)jUnit 4.x 系でテストを実装すること。
   詳細は、jUnit4.x系の使い方をご覧下さい。


2.テストケースの基本的な実装手順

Controller のテストケース(テストメソッド)の基本的な実装手順は、以下の通りです。

(1)ControllerTester#start() で、Controller のパスを指定する。

ControllerTestCase には、ControllerTester 型のインスタンス変数 tester があります。
(テスト用のヘルパークラスと思えば良いでしょう。)
これの start() メソッドを呼び出し、テスト対象の Controller の run() メソッドを呼び出します。
ちなみに、start() メソッドの引数として指定するパスは、gen-controller で指定したパスと同じです。

(2)ControllerTester#getController() で、テスト対象の Controller のインスタンスを取得する。

ここで取得したテスト対象の Controller のインスタンスに対して、以下で assert を行っていきます。

(3)Null ではないことを検証する。

assertThat(is(notNullValue())) で、テスト対象の Controller のインスタンスが null ではないことを検証します。
※assertNull() と同義です。

(4)forward か redirect かを検証する。

ControllerTester#isRedirect() で、テスト対象の Controller の戻り値が forward(メソッドのもの)か redirect(メソッドのもの)かを検証します。

(5)遷移先のパスを検証する。

ControllerTester#getDestinationPath() で、遷移先のパスを検証します。


ちなみに上記は、Ant で自動的に生成されます


3.パラメータの設定方法

検証のためにあらかじめ HttpServletRequest などにパラメータを設定しておきたい場合は、org.slim3.util.RequestLocator クラスなどを、ControllerTester#start() を実行する前に呼び出しておきます。

    HttpServletRequest request = RequestLocator.get();
    request.setAttribute("name", "iPhone");
    this.tester.start("/order/order");


RequestLocator などの使い方については、前回の「3.HttpServletRequest等へのアクセス方法」をご覧下さい。


4.validationの検証方法

想定通りに validation が機能したかを検証するためには、org.slim3.controller.validator.Errors クラスを利用します。
検証手順は、以下の通りです。

(1)リクエストから、Errors のインスタンスを取得する。

Errors のインスタンスは、リクエストにキー "errors" で登録されています。
※同インスタンスは、validation の有無および結果に関係なく登録されています。

    Errors errors =
            (Errors) request.getAttribute("errors");
(2)Errors#size() で、validation エラーの有無を検証する。

validation エラーがない場合は、size() がゼロになります。

(3)Errors#get() で、エラーメッセージを検証する。

Errors の get() メソッドにテスト対象のフィールド名を指定すると、validation エラーがあった場合に、該当するメッセージを取得・検証できます。

    assertEquals(
            "nameは必須です。",
            errors.get("name"));


ちなみに上記は、ControllerTester#start() を実行した後に呼び出せます


5.テスト用のテーブルデータの設定方法

検証のためにあらかじめテーブル(BigTable)にデータを設定しておきたい場合は、該当する Service ないし Datastore でのデータ格納操作を、ControllerTester#start() を実行する前に呼び出しておきます。


ControllerTestCase は、Service のテストケースと同様、テスト終了後に処理をロールバックしてくれます
そのため、単体テストの連続実行が可能となります。


6.【参考】テストの実装例

package xxx.yyy.controller.order;

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;

import javax.servlet.http.HttpServletRequest;

import org.junit.Test;
import org.slim3.controller.validator.Errors;
import org.slim3.tester.ControllerTestCase;
import org.slim3.util.RequestLocator;

public class OrderControllerTest
        extends ControllerTestCase {

    // ◆例:name が null で validation エラーになるケース
    @Test
    public void run_NameIsEmptyError() throws Exception {

        // ◆準備:リクエストの設定
        HttpServletRequest request = RequestLocator.get();
        request.setAttribute(
                "name",
                "");

        // ◆run() メソッドの呼び出し
        this.tester.start("/order/order");
        OrderController controller =
                this.tester.getController();

        // ◆Ant で自動生成される検証ロジック
        assertThat(
                controller,
                is(notNullValue()));
        assertThat(
                this.tester.isRedirect(),
                is(false));
        assertThat(
                this.tester.getDestinationPath(),
                is("/WEB-INF/view/order/order.jsp"));

        // ◆validation エラーの検証
        Errors errors =
                (Errors) request.getAttribute("errors");
        assertEquals(
                1,
                errors.size());
        assertEquals(
                "nameは必須です。",
                errors.get("name"));
    }
}

次の予定

次は、JSP の作成方法・ルールについて見ていこうと思います。