[[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]
皆様のご意見、ご希望をお待ちしております。

#comment

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
SmartDoc