2013年9月25日水曜日

最強モックツール JMockit その7 複数回呼び出し

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

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

さて、今まで使ってきたJMokitのソースは、ずっと「NonStrictExpectations」を使ってきました。

第三回の時に「NonStrictExpectations」でほとんど事足りると記載しましたが、ここから先はそれ以外のケースについてご説明します。

複数回呼び出し


英単語の説明から入りますが、NonStrictExpectationsの「Strict」とは日本語で『厳密な』という意味となります。Expectationは『期待』です。
つまり、NonStrictExpectationsとは『期待値の定義を厳密にしない』という意味になります。

当然ながら、「じゃあ、厳密な場合は何を厳密にするの?」というのが当然の疑問でしょう。
チェックが厳密化するのは複数あるのですが、例として「実行順序」と「実行回数」があります。
今回は「実行順序」と「実行回数」をチェックしてテストを実行する「Expectationsクラス」のご紹介です。

「実行順序」と「実行回数」をチェックしなければならないテストケースとしては、以下を想定します。

  • Webシステムのログイン機能で、ログインに失敗した後の処理をテストする。
  • ログイン失敗が1回目、2回目の時はログイン画面に戻る。3回目以降はアカウントロック画面に遷移する。

まずは本体ソースから。

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

  //リクエストからエラーになったIDを取得
  String id = req.getParameter("login_id");

  LoginService service = new LoginService();

  if(service.loginErrorCount(id) <= 2){
   return "login/login.jsp";
  }

  //ログイン失敗
  return "login/loginLock.jsp";
 }
}
これについては説明はいらないでしょう。 ログイン失敗回数がDBに保存されているので、それを取得して2回以下だったらログイン画面に戻る。 3回以上だったらアカウントロック画面に遷移します。 これに対するテストケースは以下になります。
public class LoginErrorActionTest {

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

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

 /**  LoginServiceのモック */
 @Mocked
 private LoginService loginService;

 @Test
 public void test_3回ログインに失敗するとロック画面に遷移する() {

  LoginErrorAction action = new LoginErrorAction();
  loginService = new LoginService();

  new Expectations() {{
   loginService.loginErrorCount(anyString);
   result = 1;  //ログイン失敗1回目
   result = 2;  //ログイン失敗2回目
   result = 3;  //ログイン失敗3回目
                }};

        String jsp1 = action.doAction(mockRequest, mockResponse);
        assertThat(jsp1, is("login/login.jsp"));

        String jsp2 = action.doAction(mockRequest, mockResponse);
        assertThat(jsp2, is("login/login.jsp"));

        String jsp3 = action.doAction(mockRequest, mockResponse);
        assertThat(jsp3, is("login/loginLock.jsp"));

 }

}
ほぼほぼNonStrictExpectationsの頃と変わらないのですが、Expectationsにしたことで微妙な差異が生まれています。 まずはこれです。
loginService = new LoginService();
自分でモック化するクラスをnewしています。 NonStrictExpectationsならば勝手にインスタンスを作ってくれるのでこの行は不要でした。 Expectationsは厳密な処理を行うクラスですので、そういう自動機能は使わず、自分で明示的に指定しろということなのでしょう。 次にこちら。
new Expectations() {{
   loginService.loginErrorCount(anyString);
   result = 1;  //ログイン失敗1回目
   result = 2;  //ログイン失敗2回目
   result = 3;  //ログイン失敗3回目
   }};

呼び出し順番を指定しています。
1回目は「1」、2回目は「2」、3回目は「3」を指定しています。

JMockitの複数回指定はこのように書くわけです。
この書き方自体はNonStrictExpectationsも同じでして、NonStrictExpectationsでも同じように、1回目、2回目、3回目の指定は出来ます。

ExpectationsとNonStrictExpectationsの違いは以下です。

  • Expectations:呼び出しは3回までしか出来ない。4回呼び出すとエラーになる。
  • NonStrictExpectations:呼び出しは何回でもOK。4回目以降は3回目と同じ値になる。

なるほど、やはり厳密になっていますね。
つまり、「NonStrictExpectationsを使っていたら動いていたけど、実は見落としがあってテストケースが機能していなかった」という事態を避けることが出来るわけです。
テストの品質としてはExpectationsの方が上と言えるでしょう。

しかし、全部Expectationsを使っていては工数を消費してしまいますので、「NonStrictExpectationsで簡単に済ませて良いパターン」と「Expectationsでしっかりチェックしなければならない複雑なパターン」を切り分けてコーディングしていくことが肝心です。

終わりに


引き続きJMockitのご紹介をしていきます。

0 件のコメント:

コメントを投稿