DBテスト用基底クラス
DBテスト用基底クラスを作成したので紹介します。
/** * DBテストクラス用基底クラス * @author glass-_-onion * @history */ public abstract class BaseDatabaseTestCase extends DatabaseTestCase { private Log log = LogFactory.getLog( this.getClass().getName()); private File file = null; private IDatabaseConnection conn = null; private String[] tableNames = null; public BaseDatabaseTestCase() { super(); } public BaseDatabaseTestCase(String name) { super(name); } /** * テスト対象のテーブル名を取得するメソッド */ protected final String getTableName(int index) { return tableNames[index]; } /** * テストデータXmlファイルの名前を取得するメソッド */ protected abstract String getSelectFileName(); /** * テストデータXmlファイルの名前を取得するメソッド(Insert) */ protected String getInsertFileName() { return null; } /** * テストデータXmlファイルの名前を取得するメソッド(Update) */ protected String getUpdateFileName() { return null; } /** * テストデータXmlファイルの名前を取得するメソッド(Delete) */ protected String getDeleteFileName() { return null; } /** * ログオブジェクトをを取得するメソッド */ protected Log getLog() { return log; } /** * @see DatabaseTestCase#getSetUpOperation() */ protected DatabaseOperation getSetUpOperation() throws Exception { return DatabaseOperation.NONE; } /** * @see DatabaseTestCase#getTearDownOperation() */ protected DatabaseOperation getTearDownOperation() throws Exception { return DatabaseOperation.NONE; } /** * @see DatabaseTestCase#setUp() */ protected void setUp() throws Exception { super.setUp(); try { conn = getConnection(); IDataSet dataset = getDataSet(getSelectFileName()); tableNames = dataset.getTableNames(); //元データ退避 QueryDataSet partialDataSet = new QueryDataSet(conn); for(int i = 0, n = tableNames.length; i < n; i++) { partialDataSet.addTable(tableNames[i]); } file = File.createTempFile("tmp", ".xml"); FlatXmlDataSet.write( partialDataSet, new FileOutputStream(file)); //テストデータ投入 DatabaseOperation.CLEAN_INSERT.execute(conn, dataset); } catch (Exception e) { log.error(e, e); super.fail(e.toString()); } } /** * @see DatabaseTestCase#tearDown() */ protected void tearDown() throws Exception { try { //元データ復元 IDataSet dataset = new FlatXmlDataSet(file); DatabaseOperation.CLEAN_INSERT.execute(conn, dataset); } catch (Exception e) { log.error(e, e); super.fail(e.toString()); } finally { if(conn != null) conn.close(); } super.tearDown(); } /** * @see DatabaseTestCase#getDataSet() */ protected IDataSet getDataSet() throws Exception { return getDataSet(getSelectFileName()); } /** * @see DatabaseTestCase#getConnection() */ protected IDatabaseConnection getConnection() throws Exception { Connection connection = ConnectionUtil2.getJDBCConnection(); String schema = connection.getMetaData().getUserName(); IDatabaseConnection conn = new DatabaseConnection( connection, schema); DatabaseConfig config = conn.getConfig(); config.setProperty( DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new OracleDataTypeFactory()); return conn; } /** * ファイルの取得 */ private InputStream getFileStream(String filePath) { return this.getClass().getResourceAsStream(filePath); } /** * ファイル名を指定してデータセットを取得する */ private IDataSet getDataSet(String fileName) throws Exception { ReplacementDataSet expectedDataSet = new ReplacementDataSet( new XlsDataSet(getFileStream(fileName))); expectedDataSet.addReplacementObject( "[SYSDATE]", new Date(System.currentTimeMillis())); expectedDataSet.addReplacementObject("[NULL]", null); return expectedDataSet; } /** * テスト結果として期待されるデータを取得する */ protected final ITable getExpectedTable(int index, String fileName) throws Exception { return getExpectedTable(getTableName(index), fileName); } /** * テスト結果として期待されるデータを取得する */ protected ITable getExpectedTable(String tableName, String fileName) throws Exception { IDataSet expectedDataSet = getDataSet(fileName); ITable expectedTable = expectedDataSet.getTable(tableName); return expectedTable; } /** * データベースに登録されているデータを取得する */ protected ITable getActualTable(int index) throws Exception { return getActualTable(getTableName(index)); } /** * データベースに登録されているデータを取得する */ protected ITable getActualTable(String tableName) throws Exception { IDatabaseConnection conn = null; ITable actualTable = null; try { conn = getConnection(); IDataSet actualDataSet = conn.createDataSet(); actualTable = actualDataSet.getTable(tableName); } catch (Exception e) { log.error(e, e); super.fail(e.toString()); } finally { if(conn != null) conn.close(); } return actualTable; } /** * データベースに登録されているデータ件数を取得する */ protected int getTableRowCount(String tableName) throws Exception { IDatabaseConnection conn = null; ITable actualTable = null; try { conn = getConnection(); IDataSet actualDataSet = conn.createDataSet(); actualTable = actualDataSet.getTable(tableName); } catch (Exception e) { log.error(e, e); super.fail(e.toString()); } finally { if(conn != null) conn.close(); } return actualTable.getRowCount(); } /** * 2つのテーブルを比較する */ protected void assertEqualsTable(ITable expectedTable,ITable actualTable) throws Exception { for(int i = 0, rowCount = expectedTable.getRowCount(); i < rowCount; i++){ for(int j = 0, colCount = expectedTable.getTableMetaData().getColumns().length; j < colCount; j++) { Column[] col = expectedTable .getTableMetaData() .getColumns(); String colName = col[j].getColumnName(); String expectedColValue = String.valueOf( expectedTable.getValue(i, colName)); String actualColValue = String.valueOf( actualTable.getValue(i, colName)); assertEquals("Line:" + i + " Column:" + colName, expectedColValue, actualColValue); } } } }
とこんな感じです。
このクラスではコネクションの設定や元データの退避を行ってテストデータをロードする機能を提供します。
このクラスを継承して作成したテストケースは1データパターン※のテストが実施できます。
複数のデータパターンをテストする場合はテストクラスを分けてTestSuiteで実行してください。
テストデータはExcelファイルで用意されていることを想定しています。
※select,insert,update,delete処理に対してそれぞれ1つのデータを使用すること
テスト手順
前準備
検索系テストで使用するデータファイルを設定する
getSelectFileName()をオーバーライド、return値にファイル名を指定
Insert系テストで使用するデータファイルを設定する
getInsertFileName()をオーバーライド、return値にファイル名を指定
Update系テストで使用するデータファイルを設定する
getUpdateFileName()をオーバーライド、return値にファイル名を指定
Delete系テストで使用するデータファイルを設定する
getDeleteFileName()をオーバーライド、return値にファイル名を指定
検索系テスト
検索条件なしで全件データを取ってくるか確認
1件もヒットしない条件を指定してデータが取得できないことを確認
1件ヒットする条件を指定して期待されるデータが取得できているか確認
1件以上ヒットする条件を指定して期待されるデータが取得できているか確認
Insert系
データ件数が1件増えることを確認
挿入したデータが期待されるデータと同じことを確認
主キーを重複して指定した場合、DatabaseExceptionがスローされることを確認
Update系
変更前データ件数と変更後データ件数が同じことを確認
変更したデータが期待されるデータと同じことを確認
Delete系
削除前と削除後のデータ件数の確認
削除したデータをセレクトしても該当データなしになるか確認
削除後のデータが期待されるデータと同じことを確認