2013年9月4日水曜日

最強モックツール JMockit その3 Webリクエスト編

株式会社ジェニシス 技術開発事業部の遠藤 太志郎(Tacy)です。

現在はモックツール「JMockit」をご紹介しています。

さて、JMockitというのは非常に高機能なライブラリでして、大きく分けて以下3つのAPIに分類できます。

  • Expectations API
  • Verifications API
  • Mockups API

しかしながら、現実のプロジェクトにおける開発風景を考えますと、


「Expectations API」の一部機能だけ分かっていれば十分


と言ってしまっても差し支え無いかと思います。

というわけで、各APIの掘り下げは以降の連載で追々ご紹介するとして、当面は「とりあえず使ってみる」をテーマとして、JMockitを使えばこういうことが出来るのだという実例をご紹介したいと思います。

最初は「Webリクエスト」です。

Webリクエストのモックテスト

ここで言うWebリクエストとは、「画面のフォームに値を入れてサブミットする」という一般的なWebシステムの通信に使用される、あのリクエストのことです。

例として「ログイン画面からIDとパスワードを入力してログインする」という機能をtomcatで実現する機能を挙げてみます。


public class LoginExcuteAction extends HttpServlet {
 public String doAction(HttpServletRequest req, HttpServletResponse res){

  //リクエストからログインIDとパスワードを取得
  String id = req.getParameter("login_id");
  String pw = req.getParameter("login_pw");

  /**
   * 実際にはここでDBにログイン認証を行う。
   * サンプルは文字列一致で済ませる。
   */
  if(id.equals("tacy") && pw.equals("password")){
                        //ログイン成功
   return "menu/memu.jsp";
  }

                //ログイン失敗
  return "login/loginError.jsp";
 }
}

このサンプルでテストすべきは以下機能です。

  • ログイン成功(ログインIDがtacy、パスワードがpassword)だったら、ログイン成功してメニュー画面へ進む。
  • ログイン失敗だったら、ログインエラー画面に進む。

至ってシンプルで平凡なWeb機能です。
画面で実際に手動でIDとパスワードを入れて動作確認するのであれば、簡単にテストできます。

しかし、これをJUnitで行うとしたら、どうでしょう?

そう、普通には出来ないんですよね。

と言うのも、「HttpServletRequest」「HttpServletResponse」はtomcatライブラリのクラスで、普通に「new」して作ることが出来ません。
(リクエストやレスポンスというのは、人間が画面に入力した項目以外にも色々なパラメータを持っていますからね。)

つまるところ、直球で「HttpServletRequest」「HttpServletResponse」を作ってJUnit実行とは出来ないのです。

そこで黒魔術登場です。
「HttpServletRequest」「HttpServletResponse」をモック化して、ダミーのリクエストでテストをやってしまいましょう!!


public class LoginExcuteActionTest {

 /** HttpServletRequestのモック  */
 @Mocked
 private HttpServletRequest mockRequest;

 /**  HttpServletResponseのモック */
 @Mocked
 private HttpServletResponse mockResponse;

 @Test
 public void ログインに成功してメニュー画面に遷移する() {

  LoginExcuteAction action = new LoginExcuteAction();

  new NonStrictExpectations() {{
   mockRequest.getParameter("login_id"); result = "tacy";
   mockRequest.getParameter("login_pw");result = "password";
                }};

                String jsp = action.doAction(mockRequest, mockResponse);

                assertThat(jsp, is("menu/memu.jsp"));

 }

 @Test
 public void ログインに失敗してログイン画面に遷移する() {

  LoginExcuteAction action = new LoginExcuteAction();

  new NonStrictExpectations() {{
   mockRequest.getParameter("login_id"); result = "tacy";
   mockRequest.getParameter("login_pw");result = "error";
                }};

                String jsp = action.doAction(mockRequest, mockResponse);

                assertThat(jsp, is("login/loginError.jsp"));

 }

}

まず、フィールドにアサーション「@Mocked」を宣言して「HttpServletRequest」「HttpServletResponse」のモックを作ります。
そして、各メソッドの「new NonStrictExpectations」の中で、モックとしての挙動を定義します。
最後にモックを引数として普通にメソッドを実行すれば、テスト成功です。

簡単ですね!!


終わりに


今回紹介した「@Mocked」+「new NonStrictExpectations」の組み合わせ、これがjmockitで一番簡単なやり方です。

もちろん違う書き方もあり、例えば「モックが呼ばれた回数も確認したい」「モックを呼ぶ順番も制御したい」など細かな要望にも対応可能ですが、
現実として、大概はこの「@Mocked」+「new NonStrictExpectations」で済んでしまうかと思います。

次回もjmockit活用法のサンプルをご紹介します。

0 件のコメント:

コメントを投稿