m-namikiの日記

おもしろき こともなき世を おもしろく

続・s2junit4での@Mockの使い方

昨日のコメント欄でid:taediumさんからアドバイス頂いた方法をもとに、自分なりに色々やってみた結果のまとめ。

まずjava/test/resourcesに以下のファイルを作成する。

  • env.txt
  • customizer_ut.dicon

env.txtの中身は「ut」。こうしておくとテスト実行時にcustomizer_ut.diconが読み込まれてくれる。(S2Containerの暗黙的な条件インクルード機能)

customizer_ut.diconを作ったのは、Actionを自動バインドしようとするとActionCustmizerでModulueConfigが取得できないため、NullPointerExceptionが発生してしまうので、テスト実行時にはActionCustomizerを読み込ませないようにするため。以下、その内容。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN" 
	"http://www.seasar.org/dtd/components24.dtd">
<components>
  <include path="default-customizer.dicon"/>
  <component name="formCustomizer" class="org.seasar.framework.container.customizer.CustomizerChain"/>
  <component name="actionCustomizer" class="org.seasar.framework.container.customizer.CustomizerChain">
    <initMethod name="addAspectCustomizer">
      <arg>"aop.traceInterceptor"</arg>
    </initMethod>
  </component>
  <component name="serviceCustomizer" class="org.seasar.framework.container.customizer.CustomizerChain">
    <initMethod name="addAspectCustomizer">
      <arg>"aop.traceInterceptor"</arg>
    </initMethod>
  </component>
</components>

あとは昨日のテストクラスを以下のように変更する。

@RunWith(Seasar2.class)
public class LoginActionTest {

    // テスト対象クラスです。
    private LoginAction action;

    // Mock化するServiceクラスです。
//    private EmployeeService employeeService;

    /**
     * 各テストケース実行前の初期化処理です。
     * 
     * @throws Exception
     *             何らかの例外が発生した場合
     */
    public void before() throws Exception {
//        action = new LoginAction();
//        action.loginForm = new LoginForm();
    }

    /**
     * {@link com.example.action.LoginAction#doLogin()}のテストケースです。<br>
     * このケースではログインが正常に行われた場合の挙動を検証します。
     * 
     * @throws Exception
     *             何らかの例外が発生した場合
     */
    @Test
    @Mock(target = EmployeeService.class, pointcut = "loginAuth", returnValue = "new com.example.entity.Employee()")
    public void testDoLogin() throws Exception {
//        action.employeeService = this.employeeService;
        assertEquals("/menu/?redirect=true", action.doLogin());
    }
}

これでテストを実行するとServiceがMockとして動いてくれるし、ActionもFormも自動でバインドされてくれる。うーん、すごい。