FrontPage 2008/01/15からのアクセス回数 8386
Spring-MVC用archeTypeプラグインには、単体テスト用のひな形が含まれていなかったので 1.1.0版でテストケースを取り込みました。
Spring-MVCプラグインの1.1.0のインストールには以下の4ファイルが必要です。
上記の添付ファイルをダウンロードしてください。近々公開用リポジトリを用意する予定です(それまでinstall-fileをご使用ください)。
mvn install:install-file \ -Dfile=./spring-mvc-archetype-1.1.0.jar \ -DgroupId=jp.co.pwv.spring-mvc-archetype \ -DartifactId=spring-mvc-archetype \ -Dversion=1.1.0 \ -DpomFile=./spring-mvc-archetype-1.1.0.pom \ -Dpackaging=jar mvn install:install-file \ -Dfile=./maven-GenMVC-plugin-1.1.0.jar \ -DgroupId=org.apache.maven.plugins \ -DartifactId=maven-GenMVC-plugin \ -Dversion=1.1.0 \ -DpomFile=./maven-GenMVC-plugin-1.1.0.pom \ -Dpackaging=jar
テストケースで追加されたファイルは以下の通りです。
JUnit用のjavaクラスファイルです。
これらは、main/webapp/WEB-INFのファイルと同じものを使用します。 ''特にapplicationContext.xml, servlet-stub.xmlはGenMVCプラグインを実行すると 変更されますので、test/resourcesへのコピーが必要です。''
JUnit用に以下の定義を追加しました。
<!-- TransactionManager --> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <!-- DbUnitHelperDao --> <bean id="dbUnitHelperDao" class="jp.co.pwv.utils.DbUnitHelperDao"> <property name="sessionFactory" ref="sessionFactory" /> </bean>
transactionManagerは、AbstractTransactionalSpringContextTestsが必要とし、 dbUnitHelperDaoは、DbUnitHelperDaoが必要とします。 DbUnitHelperDaoは、テストデータのdump, resotoreとprintメソッドを提供します。 GenMVCプラグインで新たにManagerクラスを追加した場合には、TestCase.javaの35行
dbUnitHelperDao.addHelper(memberManager.getHelper());
addHelperでManagerクラスのhelperを追加登録してください。
単体テストでは、デバッグ時にデータベースの状態を確認する必要がありますので、 HSQLDBのサーバ機能を使用するように変更しました。
# サーバとして使用する場合 db.url=jdbc:hsqldb:hsql://localhost
HSQLDBのインストールは、http://www.pwv.co.jp/take_public_html/DevTool/DevTool_c8.html#doc1_498 を参照してください。
DBUnitのFlatXmlDataSet形式のテストデータ記述ファイルです。 dump.xmlの内容は、
<?xml version="1.0" encoding="Windows-31J"?> <dataset> <T_MEMBER address='Nakano-ku' id='1' name='Hiroshi TAKEMOTO'/> </dataset>
のようなテーブル名をタグとし、フィールド名を属性とするXMLファイルです。
単体テストでは、検証用のデータをプログラムで用意する必要があります。これをjavaで記述すると 非常に面倒なので、Springの機能を使って検証用テストデータを作成するために用意しました。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd"> <beans> <bean id="expectedMember" class="example.test.domain.Member"> <property name="id" value="1" /> <property name="name" value="Hiroshi TAKEMOTO" /> <property name="address" value="Nakano-ku" /> </bean> </beans>
最初のバージョンと変更となるはarchetypeVersionだけです。
例題は、
mvn archetype:create \ -DgroupId=example.test \ -DartifactId=test \ -DarchetypeArtifactId=spring-mvc-archetype \ -DarchetypeGroupId=jp.co.pwv.spring-mvc-archetype \ -DarchetypeVersion=1.1.0
となります。
HSqlDBのサーバを起動します。HSqlDBをインストールしたディレクトリをHSQLDB_HOMEとすると
cd $HSQLDB_HOME/demo ./runServer.sh
Windowsの場合には、runServer.batを使用してください。
mvn testと
[INFO] Scanning for projects... [INFO] ------------------------------------------------------------------------ .... ------------------------------------------------------- T E S T S ------------------------------------------------------- Running example.test.TestCase .... MEMBER: ADDRESS='Nakano-ku' ID=1 NAME='Hiroshi TAKEMOTO' Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.953 sec Results : Tests run: 3, Failures: 0, Errors: 0, Skipped: 0 ....のように出力され、Tests run: 3で、3つのテストケースを実行し、エラーが無かったことが 分かります。
データベースを扱っているため、テストの影響がないようにAbstractTrasactionalSpringContextTestsを継承しています。
Springの設定ファイルは、getConfigLocationsメソッドで返すようにします。
public String[] getConfigLocations() { return new String[] { "WEB-INF/applicationContext.xml", "WEB-INF/custom-editor.xml", "WEB-INF/db-def.xml", "WEB-INF/servlet-def.xml", "WEB-INF/servlet-stub.xml", "testdata-def.xml" }; }
各テストでの開始の処理をonSetUpInTransactionで、終了の処理をonTearDownInTransactionで定義することができます。ひな形では、MemberManager, dbUnitHelperをApplicationContextから取得し、dbUnitHelperにmemberManagerのhelperを登録しています。
public void onSetUpInTransaction() throws Exception { super.onSetUpInTransaction(); memberManager = (MemberManager)getApplicationContext().getBean("memberManager"); dbUnitHelperDao = (DbUnitHelperDao)getApplicationContext().getBean("dbUnitHelperDao"); dbUnitHelperDao.addHelper(memberManager.getHelper()); } public void onTearDownInTransaction() throws Exception { super.onTearDownInTransaction(); }
Daoのテストの例をtestFindByIdメソッドに示します。
通常はこのようにしますが、helperのprintメソッド使う方法も例としてあげています。 testFindByIdメソッドは、以下の通りです。
public void testFindById() { dbUnitHelperDao.restore("src/test/resources/dump.xml"); Member member = memberManager.findById(new Integer(1)); assertEquals("Hiroshi TAKEMOTO", member.getName()); assertEquals("Nakano-ku", member.getAddress()); // or you can check using IMember.print method. Member expectedMember = (Member)getApplicationContext().getBean("expectedMember"); System.out.println(memberManager.print(member)); assertEquals(memberManager.print(expectedMember), memberManager.print(member)); }
EditMemberControllerのテストには、MockHttpServletRequestを使います。
testEditMemberControllerは、以下の通りです。
public void testEditMemberController() { dbUnitHelperDao.restore("src/test/resources/dump.xml"); MockHttpServletRequest req = new MockHttpServletRequest("POST","editMember.htm"); req.addParameter("id","1"); EditMemberController editMemberController = (EditMemberController)getApplicationContext().getBean("editMemberController"); ModelAndView mv = null; try { mv = editMemberController.handleRequest(req,new MockHttpServletResponse()); } catch (Exception err) { err.printStackTrace(); } Member expectedMember = (Member)getApplicationContext().getBean("expectedMember"); assertEquals("redirect:memberops/list.htm", mv.getViewName()); Member member = (Member)mv.getModel().get("member"); assertEquals(memberManager.print(expectedMember), memberManager.print(member)); }
単体テストを記述することは最初は億劫ですが、一度ひな形ができるとそのパターンをコピー・ペーストすれば 他のテストが簡単にできるので、テストケースのひな形を使って単体テストに挑戦してみてください。
この記事は、
皆様のご意見、ご希望をお待ちしております。