続・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も自動でバインドされてくれる。うーん、すごい。