SpringFrameworkをベースに開発をしてるということは、テスト時も必要な個所は(DataSourceのインジェクションや、ORM使ってたらiBATISの場合は、SqlMapClientのインジェクション)ApplicationContextの設定を引き継いだ状態でテストをしたい。Springでは予めapplicationContext.xmlを読み込んでくれるサポートクラスが存在する。
例えばDAOのテストケースであれば、AbstractTransactionalDataSourceSpringContextTestsといったクラスが提供される。また、applicationContext.xmlを読み込むよう、org.springframework.test.context.ContextConfigurationというアノテーションが用意されている。
AbstractTransactionalDataSourceSpringContextTestsを継承したテストケースを作成し、そのクラス宣言に@ContextConfigurationを付加すれば、テストケースを実行する際に、テストケースと同じパッケージ上に存在する「テストケースのクラス名-context.xml」が読み込まれるようになる。また、別の場所にあるapplicationContext.xmlを読み込む場合は、@ContextConfigurationにlocationを指定すれば良い。
こんな感じ
package org.hoge.dao; import org.springframework.test.AbstractTransactionalDataSourceSpringContextTests; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.ContextConfiguration; import org.junit.runner.RunWith; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration( locations = {"/applicationContext.xml", "/applicationContext-dao.xml"}) public class AbstractDaoTestCase extends AbstractTransactionalDataSourceSpringContextTests { }
@ContextConfigurationアノテーションは、@Inheritedアノテーションを定義しているアノテーションになるため、サブクラスにもアノテーションの定義内容が継承される。そのため共通で使用するapplicationContext.xmlを読み込むAbstractDaoTestCaseのようなものクラスを用意して、個別のテストケース毎にテスト用のapplicationContext.xmlを読み込ませたい場合にのみサブクラスで@ContextConfigurationを定義するといった使い方が良さげだ。
あとはテスト対象のオブジェクトをSpringにインジェクションさせるにはテストケースのフィールドとして対象のオブジェクトを定義し、@Autowiredアノテーションを付加すれば良い。Springに依存することなく、JSR-250に従うのであれば、@Resourceアノテーションを利用する。
import javax.annotation.Resource; ... @Resource private HogeEntityDao hogeEntityDao;
としておけば、hogeEntityDaoというIDでBean定義されたクラスのオブジェクトがインジェクションされるので、あとは各テストメソッドでそれらを利用してテストコードを書けば良い。