前回の
では、Unitils アサーションユーティリティについて見てきました。今回は Unitils のデータベーステストのサポートについて見ていきます。
Unitils のDBサポート環境構築
Spring + Hibernate の環境で、Unitils のDBサポートを見ていきます。まずは、環境構築から行います。前回までは Unitils 2.4 を使用していましたが、ここから3.0を使用していきます(特に理由はありません)。
前回までと同様 Maven にてプロジェクト作成します。以下のように指定し、その他はデフォルトを選択します。
> mvn archetype:generate Define value for groupId: : etc9 Define value for artifactId: : unitils-db
続いて作成された pom.xml を以下のように編集します。Unitils 3.0 からはモジュール化が進んでいるため、unitils-core のようにモジュールを指定します。Hibernate をアノテーションベースで使用するため、hibernate-annotations を指定します。また、データベースは hsqldb を使用するため、これも指定します。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>etc9</groupId> <artifactId>unitils-db</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> <name>unitils-db</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>org.unitils</groupId> <artifactId>unitils-core</artifactId> <version>3.0</version> </dependency> <dependency> <groupId>org.unitils</groupId> <artifactId>unitils-orm</artifactId> <version>3.0</version> </dependency> <dependency> <groupId>org.unitils</groupId> <artifactId>unitils-dbunit</artifactId> <version>3.0</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-annotations</artifactId> <version>3.4.0.GA</version> </dependency> <dependency> <groupId>hsqldb</groupId> <artifactId>hsqldb</artifactId> <version>1.8.0.7</version> </dependency> </dependencies> </project>
eclipse のプロジェクトに変換します。
> cd unitils-db > mvn eclipse:eclipse
以下が依存として追加されます。大量です・
o hsqldb:hsqldb:1.8.0.7 o org.hibernate:hibernate-annotations:3.4.0.GA o org.hibernate:ejb3-persistence:1.0.2.GA o org.hibernate:hibernate-commons-annotations:3.1.0.GA o org.slf4j:slf4j-api:1.4.2 o org.hibernate:hibernate-core:3.3.0.SP1 o antlr:antlr:2.7.6 o commons-collections:commons-collections:3.2 o dom4j:dom4j:1.6.1 o xml-apis:xml-apis:1.0.b2 o javax.transaction:jta:1.1 o org.unitils:unitils-core:3.0 o junit:junit:4.4 o commons-logging:commons-logging:1.1 o commons-lang:commons-lang:2.3 o ognl:ognl:2.6.9 o org.unitils:unitils-dbunit:3.0 o org.unitils:unitils-database:3.0 o org.unitils:unitils-dbmaintainer:3.0 o org.hibernate:hibernate:3.2.5.ga o net.sf.ehcache:ehcache:1.2.3 o asm:asm-attrs:2.2.3 o cglib:cglib:2.2 o asm:asm:3.1 o org.dbunit:dbunit:2.2.2 o junit-addons:junit-addons:1.4 o xerces:xercesImpl:2.6.2 o xerces:xmlParserAPIs:2.6.2 o poi:poi:2.5.1-final-20040804 o org.slf4j:slf4j-nop:1.4.3 o commons-dbcp:commons-dbcp:1.2.2 o commons-pool:commons-pool:1.3 o org.springframework:spring-jdbc:2.5.2 o org.springframework:spring-beans:2.5.2 o org.springframework:spring-core:2.5.2 o org.springframework:spring-context:2.5.2 o aopalliance:aopalliance:1.0 o org.springframework:spring-tx:2.5.2 o org.unitils:unitils-orm:3.0 o org.unitils:unitils-spring:3.0 o org.springframework:spring-test:2.5.2 o org.springframework:spring-orm:2.5.2 o javax.persistence:persistence-api:1.0
この辺の依存関係はバージョン違いなどで意味不明なエラーとなるので注意。
あとはeclipse にインポートです。
Spring + Hibernate によるテスト用アプリ作成
Unitils の動作確認用に、Spring + Hibernate にて簡単なテスト用のアプリケーションを作成します。まずは、Entity となる Item クラスを作成します。
import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @Entity public class Item { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
作成したItemクラスを検索するためのDaoのインターフェースと実装を作成します。
import java.util.List; public interface ItemDao { Item get(Long id); Item save(Item item); List<Item> findByName(Item item); }
import java.util.List; import org.hibernate.SessionFactory; import org.hibernate.criterion.DetachedCriteria; import org.hibernate.criterion.Example; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.orm.hibernate3.HibernateTemplate; public class ItemDaoImpl implements ItemDao { private HibernateTemplate hibernateTemplate; @Autowired public void setSessionFactory(SessionFactory sessionFactory) { this.hibernateTemplate = new HibernateTemplate(sessionFactory); } @Override public Item get(final Long id) { return (Item) this.hibernateTemplate.get(Item.class, id); } @Override public Item save(final Item item) { this.hibernateTemplate.save(item); return item; } @SuppressWarnings("unchecked") @Override public List<Item> findByName(Item item) { DetachedCriteria criteria = DetachedCriteria.forClass(Item.class); criteria.add(Example.create(item).enableLike()); return hibernateTemplate.findByCriteria(criteria); } }
findByName メソッドでは、Like 検索を行うため、enableLike() を指定しています。
作成した Dao を使い、Item を取得するサービスを作成します。
import java.util.List; import org.springframework.beans.factory.annotation.Autowired; public class ItemService { private ItemDao itemDao; @Autowired public void setItemDao(ItemDao itemDao) { this.itemDao = itemDao; } public void addNewItem(String name) { Item item = new Item(); item.setName(name); itemDao.save(item); } public Item getItem(Long id) { return itemDao.get(id); } public List<Item> findByName(String name) { Item item = new Item(); item.setName(name); return itemDao.findByName(item); } }
次に Spring の設定ファイルを作成します。ソースフォルダの直下に applicationContext.xml を以下の内容で作成します。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"> <context:annotation-config/> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" destroy-method="close"> <property name="driverClassName" value="org.hsqldb.jdbcDriver"/> <property name="url" value="jdbc:hsqldb:mem:etc9-unitils"/> <property name="username" value="sa"/> <property name="password" value=""/> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="hibernateProperties"> <value> hibernate.dialect = org.hibernate.dialect.HSQLDialect hibernate.show_sql = true hibernate.format_sql = true hibernate.hbm2ddl.auto = create </value> </property> <property name="annotatedClasses"> <list><value>etc9.Item</value></list> </property> </bean> <bean id="itemService" class="etc9.ItemService"> </bean> <bean id="itemDao" class="etc9.ItemDaoImpl"> </bean> </beans>
@Autowired を有効にするために
<property name="url" value="jdbc:hsqldb:mem:etc9-unitils"/>
ここまで作成したアプリケーションを動作させてみます。Main クラスを以下のように作成し、アプリケーションを実行して Item の内容が表示されれば ここまでの準備は完了です。
import org.apache.commons.lang.builder.ToStringBuilder; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext( "applicationContext.xml"); ItemService service = (ItemService) context.getBean("itemService"); service.addNewItem("item1"); service.addNewItem("item2"); service.addNewItem("item3"); System.out.println(ToStringBuilder.reflectionToString(service.getItem(1L))); for (Item i : service.findByName("item%")) { System.out.println(ToStringBuilder.reflectionToString(i)); } } }
Unitils の環境作成
ここからは、Unitils による DB アクセステストのための設定を行っていきます。Unitils にて DB を用いたテストを行うためには、Unitils の設定ファイルを用意する必要があり、以下の3種類があります。
- unitils-defaults.properties:Unitils の Jar に含まれているデフォルト設定の定義
- unitils.properties:プロジェクトレベルでの Unitils の設定
- unitils-local.properties:パッケージなどのプロジェクトレベルより細かい Unitils の設定
ここでは、unitils.properties のみを扱います。unitils-local.properties を作成した場合は、unitils.properties の定義を上書く形で、より細かい単位での設定が可能です。
ソースフォルダの直下に以下の unitils.properties を作成します。通常、テスト用のソースフォルダの直下となるでしょう。
database.driverClassName=org.hsqldb.jdbcDriver database.url=jdbc:hsqldb:mem:etc9-unitils database.userName=sa database.password= database.schemaNames=PUBLIC database.dialect=hsqldb
この定義ファイルで、Unitils 使用時のデータベースの接続先を指定します。schemaNames は省略できないため、PUBLIC のように、使用するデータベースに合わせたスキーマ名を指定する必要がある点に注意してください。
続いて、上記の Unitils の設定ファイルを Spring の定義ファイルから読み込むよう、applicationTestContext.xml のような名前でファイルを作成し以下の内容とします。この dataSource の設定により、unitils.properties に定義したの接続情報に基づきテストが行われることになります。なお、本ファイルもテスト用のソースフォルダの直下に配置してください。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="dataSource" class="org.unitils.database.UnitilsDataSourceFactoryBean" /> </beans>