- 追加された行はこの色です。
- 削除された行はこの色です。
#freeze
[[FrontPage]]
2008/01/15からのアクセス回数 &counter;
#contents
* Spring-MVCプラグイン機能追加(テストケース) [#a8a163c0]
Spring-MVC用archeTypeプラグインには、単体テスト用のひな形が含まれていなかったので
1.1.0版でテストケースを取り込みました。
** Spring-MVCプラグイン1.1.0のインストール [#b55bf04e]
Spring-MVCプラグインの1.1.0のインストールには以下の4ファイルが必要です。
- archeTypeプラグインjarファイル
#ref(spring-mvc-archetype-1.1.0.jar);
- archeTypeプラグインpomファイル
#ref(spring-mvc-archetype-1.1.0.pom);
- GenMVCプラグインjarファイル
#ref(maven-GenMVC-plugin-1.1.0.jar);
- GenMVCプラグインpomファイル
#ref(maven-GenMVC-plugin-1.1.0.pom);
上記の添付ファイルをダウンロードしてください。近々公開用リポジトリを用意する予定です(それまでinstall-fileをご使用ください)。
- 次に以下のコマンドを実行してください。
#pre{{
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
}}
** テストケースで追加されたファイル [#vf21bddd]
テストケースで追加されたファイルは以下の通りです。
#ref(fileTree.jpg);
- test/java/example/test/TestCase.java
JUnit用のjavaクラスファイルです。
- test/resources/WEB-INF/applicationContext.xml
- test/resources/WEB-INF/custom-editor.xml
- test/resources/WEB-INF/servlet-def.xml
- test/resources/WEB-INF/servlet-stub.xml
- test/resources/WEB-INF/hbm-dir/Member.hbm.xml
これらは、main/webapp/WEB-INFのファイルと同じものを使用します。
''特にapplicationContext.xml, servlet-stub.xmlはGenMVCプラグインを実行すると
変更されますので、test/resourcesへのコピーが必要です。''
- test/resources/WEB-INF/db-def.xml(変更あり)
JUnit用に以下の定義を追加しました。
#pre{{
<!-- 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行
#pre{{
dbUnitHelperDao.addHelper(memberManager.getHelper());
}}
addHelperでManagerクラスのhelperを追加登録してください。
- test/resources/WEB-INF/jdbc.properties.xml(変更あり)
単体テストでは、デバッグ時にデータベースの状態を確認する必要がありますので、
HSQLDBのサーバ機能を使用するように変更しました。
#pre{{
# サーバとして使用する場合
db.url=jdbc:hsqldb:hsql://localhost
}}
HSQLDBのインストールは、http://www.pwv.co.jp/take_public_html/DevTool/DevTool_c8.html#doc1_498
を参照してください。
- test/resources/dump.xml(新規追加)
DBUnitのFlatXmlDataSet形式のテストデータ記述ファイルです。
dump.xmlの内容は、
#pre{{
<?xml version="1.0" encoding="Windows-31J"?>
<dataset>
<T_MEMBER
address='Nakano-ku'
id='1'
name='Hiroshi TAKEMOTO'/>
</dataset>
}}
のようなテーブル名をタグとし、フィールド名を属性とするXMLファイルです。
- test/resources/testdata-def.xml(新規追加)
単体テストでは、検証用のデータをプログラムで用意する必要があります。これをjavaで記述すると
非常に面倒なので、Springの機能を使って検証用テストデータを作成するために用意しました。
#pre{{
<?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>
}}
** ひな形の作成 [#kb6a3c0e]
最初のバージョンと変更となるはarchetypeVersionだけです。
例題は、
#pre{{
mvn archetype:create \
-DgroupId=example.test \
-DartifactId=test \
-DarchetypeArtifactId=spring-mvc-archetype \
-DarchetypeGroupId=jp.co.pwv.spring-mvc-archetype \
-DarchetypeVersion=1.1.0
}}
となります。
** 単体テストの実行 [#f392e208]
- HSqlDBのサーバ
HSqlDBのサーバを起動します。HSqlDBをインストールしたディレクトリをHSQLDB_HOMEとすると
#pre{{
cd $HSQLDB_HOME/demo
./runServer.sh
}}
Windowsの場合には、runServer.batを使用してください。
- mvnでのテスト
次にmvnで単体テストを実行します。
#pre{{
mvn test
}}
と
#pre{{
[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つのテストケースを実行し、エラーが無かったことが
分かります。
** テストケースについて [#xbf14bcf]
*** 設定の前準備 [#u49ec2c0]
- TestCaseの選択
データベースを扱っているため、テストの影響がないようにAbstractTrasactionalSpringContextTestsを継承しています。
- Spring設定ファイル
Springの設定ファイルは、getConfigLocationsメソッドで返すようにします。
#pre{{
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を登録しています。
#pre{{
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();
}
}}
*** memberManager(Daoのテスト) [#de284dd9]
Daoのテストの例をtestFindByIdメソッドに示します。
- dbUnitHelperDaoのresotreメソッドでデータベースにテストデータをセットします
- DaoのfindByIdメソッドでmemberを取得します。
- assertEqualsで値の確認をします。
通常はこのようにしますが、helperのprintメソッド使う方法も例としてあげています。
testFindByIdメソッドは、以下の通りです。
#pre{{
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(コントローラのテスト) [#xcde89d9]
EditMemberControllerのテストには、MockHttpServletRequestを使います。
- 第1引数でPOSTまたはGETを指定し、第2引数にURLを指定します
- addParameterメソッドでパラメータを追加します
- editMemberControllerをApplicationContextから取得し、handleRequestメソッドを呼び出します
- handleRequestの戻り値としてModelAndViewが返されます
- ModelAndViewからビューの名前とモデルからmemberの値を確認します
testEditMemberControllerは、以下の通りです。
#pre{{
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));
}
}}
** 簡単単体テスト [#z25f1e26]
単体テストを記述することは最初は億劫ですが、一度ひな形ができるとそのパターンをコピー・ペーストすれば
他のテストが簡単にできるので、テストケースのひな形を使って単体テストに挑戦してみてください。
** コメント [#gcda2a35]
この記事は、
#vote(おもしろかった,そうでもない,わかりずらい)
#vote(おもしろかった[0],そうでもない[1],わかりずらい[0])
皆様のご意見、ご希望をお待ちしております。
#comment_kcaptcha