DBのユニットテスト② Java
前回の続きです。
userテーブルに対応するBeanとDaoを作ってみます。
User.java
userテーブルと同じ構成のBeanです。
toString()とequals()はApache Commons Langを使うと楽に実装できます。
package sample; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.ToStringBuilder; public class User { private int id; private String name; public User() { } public User(int id, String name) { this.id = id; this.name = name; } public int getId() { return this.id; } public void setId(int id) { this.id = id; } public String getName() { return this.name; } public void setName(String name) { this.name = name; } public String toString() { return ToStringBuilder.reflectionToString(this); } public boolean equals(Object obj) { return EqualsBuilder.reflectionEquals(this, obj); } }
UsrDao.java
DaoはなんとなくApache Commons dbutilsで実装してみました。
SQLベースなので、個人的にdbutilsは好みです。
userテーブルに対して、
SELECT/INSERT/UPDATE/DELETEするメソッドを実装しておきます。
package sample; import java.sql.Connection; import java.sql.SQLException; import java.util.List; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanHandler; import org.apache.commons.dbutils.handlers.BeanListHandler; public class UserDao { private Connection con; private QueryRunner qr = new QueryRunner(); public UserDao(Connection con) { this.con = con; } public List<User> selectAll() throws SQLException { BeanListHandler<User> handler = new BeanListHandler<User>(User.class); return (List<User>) this.qr.query(con, "SELECT * FROM user ORDER BY id ASC", handler); } public User select(int id) throws SQLException { Object[] params = new Object[] { id }; BeanHandler<User> handler = new BeanHandler<User>(User.class); return (User) this.qr.query(con, "SELECT * FROM user WHERE id = ?", handler, params); } public void insert(User user) throws SQLException { Object[] params = new Object[] { user.getId(), user.getName() }; this.qr.update(con, "INSERT INTO user(id,name) VALUES(?,?)", params); } public void update(User user) throws SQLException { Object[] params = new Object[] { user.getName(), user.getId() }; this.qr.update(con, "UPDATE user SET name = ? WHERE id = ?", params); } public void delete(int id) throws SQLException { Object[] params = new Object[] { id }; this.qr.update(con, "DELETE FROM user WHERE id = ?", params); } }
UserDaoのテストクラス作成を簡単にする為に、ユーティリティクラスも作ってみます。
Dbcp.java
DBコネクションを管理するクラスです。
Apache Commons DBCPでコネクションプーリングします。
DB接続情報はdbcp.propertiesで外出しにしておきます。
package sample; import java.io.FileInputStream; import java.sql.Connection; import java.sql.SQLException; import java.util.Properties; import javax.sql.DataSource; import org.apache.commons.dbcp.BasicDataSourceFactory; public class Dbcp { private static Dbcp instance; private DataSource ds; public static Dbcp getInstance() throws Throwable { if (Dbcp.instance == null) { Dbcp.instance = new Dbcp(); } return Dbcp.instance; } private Dbcp() throws Throwable { Properties properties = new Properties(); properties.load(new FileInputStream("dbcp.properties")); this.ds = BasicDataSourceFactory.createDataSource(properties); } public Connection getConnection() throws SQLException { return this.ds.getConnection(); } }
dbcp.properties
DB接続情報の他に、コネクションプーリングに関する設定が記述できます。
今回はサンプルなんで設定値は適当です(;´Д`)
driverClassName=org.h2.Driver url=jdbc:h2:tcp://XXX.XXX.XXX.XXX/~/test username=sa password= # オートコミットモード defaultAutoCommit=false # コネクションプールの初期コネクション数 initialSize=5 # 最大コネクション数 maxActive=10 # アイドル状態(未使用状態)の最大コネクション数 maxIdle=10 # コネクション取得の待ち時間 maxWait=5000 # コネクションが利用可能か検証するためのSQL validationQuery=select count(*) from dual
DbTester.java
DBの初期値設定とアサートを行うクラスです。
DbUnitを使うと数行で実装できてしまいますね。
テストデータはExcelファイルで用意するのでApache POIが必要になります。
initDbメソッドで、ExcelファイルのデータをDBへ投入し、
assertDbメソッドで、ExcelファイルのデータとDBのデータを比較します。
package sample; import java.io.File; import java.sql.Connection; import org.dbunit.Assertion; import org.dbunit.database.DatabaseConnection; import org.dbunit.database.IDatabaseConnection; import org.dbunit.dataset.excel.XlsDataSet; import org.dbunit.operation.DatabaseOperation; public class DbTester { private IDatabaseConnection connection; public void setUp(Connection conn) throws Throwable { this.connection = new DatabaseConnection(conn); } public void tearDown() throws Throwable { this.connection.close(); } public void initDb(String xlsFilePath) throws Throwable { XlsDataSet dataset = new XlsDataSet(new File(xlsFilePath)); DatabaseOperation.CLEAN_INSERT.execute(this.connection, dataset); } public void assertDb(String xlsFilePath) throws Throwable { XlsDataSet expected = new XlsDataSet(new File(xlsFilePath)); Assertion.assertEquals(expected, this.connection.createDataSet(expected.getTableNames())); } }