データベースのデータをXMLに出力し、そのXMLのデータを使ったテスト方法です。
テストメソッドが実行されるたびにデータを削除し出力したXMLのデータをInsertするので、毎回同じデータでテストが実行できます。
InsertやDeleteのテスト後のSelectのテストでも結果が変わったりすることはありません。
exml.zip
dtdparser.zip
上記2つのファイルを解凍したフォルダ
を適当な場所へ配置する。
*これはXMLデータ書き出し用です。dbUnitの設定は dbUnit設定方法で。
データベースからデータを取得しXMLに書き出すプログラムです。
DataExport.java
01 package common; 02 03 import java.io.FileWriter; 04 import java.sql.Connection; 05 import java.sql.DriverManager; 06 07 import org.dbunit.database.DatabaseConnection; 08 import org.dbunit.database.IDatabaseConnection; 09 import org.dbunit.dataset.IDataSet; 10 import org.dbunit.dataset.xml.FlatDtdDataSet; 11 import org.dbunit.dataset.xml.FlatXmlDataSet; 12 13 /** 14 * @author 15 */ 16 public class DataExport { 17 18 private static final String TEST_DATA_DIRECTORY = "D:/wiki/"; 19 private static final String DATA_FILE_NAME = "dbUnitTest.xml"; 20 private static final String DTD_FILE_NAME = "dbUnitTest.dtd"; 21 22 private static final String DRIVER_CLASS_NAME = "oracle.jdbc.driver.OracleDriver"; 23 private static final String DATABASE_URL = "jdbc:oracle:thin:@localhost:1521:DJWiki"; 24 private static final String DATABASE_USER_NAME = "djwiki"; 25 private static final String DATABASE_PASSWORD = "djwiki"; 26 private static final String DATABASE_SCHEMA = "DJWIKI"; 27 28 private static final String ENCODING = "Shift_jis"; 29 30 public static void main(String[] args) throws Exception { 31 32 // database connection 33 Class.forName(DRIVER_CLASS_NAME); 34 35 Connection jdbcConnection = 36 DriverManager.getConnection(DATABASE_URL, DATABASE_USER_NAME, DATABASE_PASSWORD); 37 38 IDatabaseConnection connection = new DatabaseConnection(jdbcConnection, DATABASE_SCHEMA); 39 40 System.out.println("Schema : " + connection.getSchema()); 41 42 // partial database export 43 String[] tableNames = 44 { 45 "USER_TABLE" 46 }; 47 48 System.out.println("対象テーブル"); 49 for (int idx = 0; idx < tableNames.length; idx++) { 50 System.out.println(tableNames[idx]); 51 } 52 53 IDataSet partialDataSet = connection.createDataSet(tableNames); 54 55 System.out.println("<< データExport開始 >>"); 56 57 FlatXmlDataSet.write( 58 partialDataSet, 59 new FileWriter(TEST_DATA_DIRECTORY + DATA_FILE_NAME), 60 ENCODING); 61 62 System.out.println("<< データExport終了 >>"); 63 64 System.out.println("<< DTDExport開始 >>"); 65 66 FlatDtdDataSet.write( 67 partialDataSet, 68 new FileWriter(TEST_DATA_DIRECTORY + DTD_FILE_NAME)); 69 70 System.out.println("<< DTDExport終了 >>"); 71 } 72 }
|
*上記で配置した「exml」「dtdparser」フォルダ内にある
に対してパスを通しておきます。
●設定が必要な箇所
- 18:ここで設定されたパスにファイルが生成されます。
- 19:出力されるXMLファイル名(原則としてテストケースと同じ名前にします。)
- 20:出力されるDTDファイル名(原則としてテストケースと同じ名前にします。)
- 22:データベースドライバのクラス名
- 23:データベースのURL
- 24:データベースのユーザ名
- 25:データベースのパスワード
- 26:データベースのスキーマ名(ユーザ名を大文字にしたもの)
但し、PostgreSQLはスキーマという概念が存在しないので空にする。
- 45:出力したいテーブルの名前(Stringの配列)
以上の設定が完了したら実行します。
18行目で設定したパスに2つのファイルが出来ています。
dbUnitを使用したテストケースを用意します。
DBUnitTestCase.java
001 package common; 002 003 import java.sql.Connection; 004 005 import junit.framework.TestCase; 006 007 import org.dbunit.database.DatabaseConnection; 008 import org.dbunit.database.IDatabaseConnection; 009 010 /** 011 * @author 012 */ 013 public class DBUnitTestCase extends TestCase { 014 015 /** 016 * 実行クラス名(~Test)を取得し, DbUnitTestDataManagerクラスのフィールドに設定する. 017 * 018 * @param name TestCaseクラスのコンストラクタに与える引数 019 * @see junit.framework.TestCase#TestCase(String name) 020 */ 021 public DBUnitTestCase(String name) { 022 super(name); 023 024 dataManager = new DBUnitTestDataManager(getClassName()); 025 } 026 027 /** 028 * IDatabaseConnectionを生成し, DbUnitTestDataManagerのsetUp()を実行. 029 * 030 * @see junit.framework.TestCase#setUp() 031 */ 032 public void setUp() throws Exception { 033 super.setUp(); 034 035 conn = dataManager.getConnection(); 036 037 dataManager.setUp(conn); 038 } 039 040 /** 041 * DbUnitTestDataManagerのtearDown()を実行し, IDatabaseConnectionを破棄. 042 * 043 * @see junit.framework.TestCase#tearDown() 044 */ 045 protected void tearDown() throws Exception { 046 super.tearDown(); 047 048 dataManager.tearDown(conn); 049 050 conn = null; 051 } 052 053 /** 054 * 実行クラス名を返却する. 055 * 返却する文字列は実行クラス名の".class"を消去したもの. 056 * 057 * @return 実行クラス名 058 */ 059 private String getClassName() { 060 return getClass().getName().substring(getClass().getName().lastIndexOf(".") + 1); 061 } 062 063 /** 064 * IDatabaseConnectionを取得する. 065 * 066 * @return org.dbunit.database.IDatabaseConnection 067 * @throws Exception 予期しない例外が発生した場合 068 */ 069 protected IDatabaseConnection getConnection() throws Exception { 070 return dataManager.getConnection(); 071 } 072 073 /** 074 * テーブル名を変更する. 075 * 076 * @param conn org.dbunit.database.IDatabaseConnection 077 * @param tableName 変更前のテーブル名 078 * @param newTableName 変更後のテーブル名 079 * @throws Exception 予期しない例外が発生した場合 080 */ 081 protected void renameTable(IDatabaseConnection conn, String tableName, String newTableName) 082 throws Exception { 083 084 try { 085 dataManager.executeBatchStatement(conn, "RENAME " + tableName + " TO " + newTableName); 086 } catch (Exception e) { 087 throw new Exception("Rename Table Failed ..."); 088 } 089 } 090 091 /** 092 * テーブル名を変更する. 093 * java.sql.Connection → conn org.dbunit.database.IDatabaseConnection. 094 * 095 * @param conn java.sql.Connection 096 * @param tableName 変更前のテーブル名 097 * @param newTableName 変更後のテーブル名 098 * @throws Exception 予期しない例外が発生した場合 099 */ 100 protected void renameTable(Connection conn, String tableName, String newTableName) 101 throws Exception { 102 103 renameTable(new DatabaseConnection(conn), tableName, newTableName); 104 } 105 106 /** 107 * SQLを実行する. 108 * 109 * @param conn org.dbunit.database.IDatabaseConnection 110 * @param sql 実行するSQL 111 * @throws Exception 予期しない例外が発生した場合 112 */ 113 public void executeStatement(IDatabaseConnection conn, String sql) throws Exception { 114 dataManager.executeBatchStatement(conn, sql); 115 } 116 117 /** 118 * 複数のSQLを実行する. 119 * 120 * @param conn org.dbunit.database.IDatabaseConnection 121 * @param sqls 実行するSQL 122 * @throws Exception 予期しない例外が発生した場合 123 */ 124 public void executeStatement(IDatabaseConnection conn, String[] sqls) throws Exception { 125 dataManager.executeBatchStatement(conn, sqls); 126 } 127 128 /** 129 * SQLを実行する. 130 * java.sql.Connection → conn org.dbunit.database.IDatabaseConnection. 131 * 132 * @param conn java.sql.Connection 133 * @param sql 実行するSQL 134 * @throws Exception 予期しない例外が発生した場合 135 */ 136 public void executeStatement(Connection conn, String sql) throws Exception { 137 dataManager.executeBatchStatement(new DatabaseConnection(conn), sql); 138 } 139 140 /** 141 * 複数のSQLを実行する. 142 * java.sql.Connection → conn org.dbunit.database.IDatabaseConnection. 143 * 144 * @param conn java.sql.Connection 145 * @param sqls 実行するSQL 146 * @throws Exception 予期しない例外が発生した場合 147 */ 148 public void executeStatement(Connection conn, String[] sqls) throws Exception { 149 dataManager.executeBatchStatement(new DatabaseConnection(conn), sqls); 150 } 151 152 /** org.dbunit.database.IDatabaseConnection */ 153 protected IDatabaseConnection conn; 154 155 private DBUnitTestDataManager dataManager; 156 } |
DBUnitTestDataManager.java
001 package common; 002 003 import java.io.FileNotFoundException; 004 import java.io.FileReader; 005 import java.sql.Connection; 006 import java.sql.DriverManager; 007 008 import org.dbunit.database.DatabaseConnection; 009 import org.dbunit.database.IDatabaseConnection; 010 import org.dbunit.database.statement.IBatchStatement; 011 import org.dbunit.database.statement.StatementFactory; 012 import org.dbunit.dataset.IDataSet; 013 import org.dbunit.dataset.xml.FlatDtdDataSet; 014 import org.dbunit.dataset.xml.FlatXmlDataSet; 015 import org.dbunit.operation.DatabaseOperation; 016 017 /** 018 * @author 019 */ 020 public class DBUnitTestDataManager { 021 022 public DBUnitTestDataManager() { 023 } 024 025 /** 026 * テストファイル名をフィールドに設定する. 027 * 028 * @param testDataFile テストファイル名 029 */ 030 public DBUnitTestDataManager(String testDataFile) { 031 this.testDataFile = testDataFile; 032 } 033 034 /** 035 * テストファイルを読み込んで, データベースへ書き込みを行う. 036 * 037 * @param conn org.dbunit.database.IDatabaseConnection 038 * @throws Exception 予期しない例外が発生した場合 039 */ 040 public void setUp(IDatabaseConnection conn) throws Exception { 041 042 databaseProperties = getDatabaseProperties(); 043 dataSet = createDataSet(testDataFile); 044 045 if (dataSet != null) { 046 DatabaseOperation.CLEAN_INSERT.execute(conn, dataSet); 047 conn.getConnection().commit(); 048 } 049 } 050 051 /** 052 * データベース内容の全消去を行う. 053 * 054 * @param conn org.dbunit.database.IDatabaseConnection 055 * @throws Exception 予期しない例外が発生した場合 056 */ 057 public void tearDown(IDatabaseConnection conn) throws Exception { 058 059 try { 060 if (dataSet != null) { 061 DatabaseOperation.DELETE_ALL.execute(conn, dataSet); 062 conn.getConnection().commit(); 063 } 064 } finally { 065 conn.close(); 066 } 067 068 databaseProperties = null; 069 conn = null; 070 dataSet = null; 071 } 072 073 /** 074 * DatabasePropertiesからデータベース情報を取得し, コネクションを取得する. 075 * 076 * @return IDatabaseConnection org.dbunit.database.IDatabaseConnection 077 * @throws Exception 予期しない例外が発生した場合 078 */ 079 protected IDatabaseConnection getConnection() throws Exception { 080 081 databaseProperties = getDatabaseProperties(); 082 083 Class.forName(databaseProperties.getDriverClassName()); 084 085 Connection jdbcConnection = 086 DriverManager.getConnection( 087 databaseProperties.getDatabaseUrl(), 088 databaseProperties.getDatabaseUserName(), 089 databaseProperties.getDatabasePassword()); 090 091 jdbcConnection.setAutoCommit(false); 092 093 return new DatabaseConnection(jdbcConnection, databaseProperties.getDatabaseSchema()); 094 } 095 096 /** 097 * DatabasePropertiesを生成し返却する. 098 * 099 * @return DatabaseProperties 100 * @throws Exception 101 */ 102 private DatabaseProperties getDatabaseProperties() throws Exception { 103 return DatabaseProperties.create(); 104 } 105 106 /** 107 * 引数で渡されたファイル名を元に, dtdファイルとxmlファイルを読み込み, IDataSetを生成し返却する. 108 * 109 * @param testDataFile テストファイル名 110 * @return IDataSet 111 */ 112 protected IDataSet createDataSet(String fileName) throws Exception { 113 114 if (fileName == null) 115 return null; 116 117 FlatDtdDataSet dtdDataSet = null; 118 try { 119 dtdDataSet = 120 new FlatDtdDataSet( 121 new FileReader( 122 databaseProperties.getTestDataDirectory() + "/" + fileName + ".dtd")); 123 } catch (FileNotFoundException fnfe) { 124 } 125 126 IDataSet dataSet = null; 127 try { 128 if (dtdDataSet != null) { 129 dataSet = 130 new FlatXmlDataSet( 131 new FileReader( 132 databaseProperties.getTestDataDirectory() + "/" + fileName + ".xml"), 133 dtdDataSet); 134 } else { 135 dataSet = 136 new FlatXmlDataSet( 137 new FileReader( 138 databaseProperties.getTestDataDirectory() + "/" + fileName + ".xml")); 139 } 140 } catch (FileNotFoundException e) { 141 } 142 143 return dataSet; 144 } 145 146 /** 147 * 与えられたSQLを実行する. 148 * 149 * @param conn org.dbunit.database.IDatabaseConnection 150 * @param sql 実行するSQL 151 * @throws Exception 予期しない例外が発生した場合 152 */ 153 public void executeBatchStatement(IDatabaseConnection conn, String sql) throws Exception { 154 155 if (sql == null) { 156 return; 157 } 158 159 if (conn == null) { 160 return; 161 } 162 163 String[] sqls = new String[1]; 164 sqls[0] = sql; 165 166 executeBatchStatement(conn, sqls); 167 } 168 169 /** 170 * 与えられた複数のSQLを実行する. 171 * 172 * @param conn org.dbunit.database.IDatabaseConnection 173 * @param sqls 複数の実行するSQL 174 * @throws Exception 予期しない例外が発生した場合 175 */ 176 public void executeBatchStatement(IDatabaseConnection conn, String[] sqls) throws Exception { 177 178 if (sqls == null) { 179 return; 180 } 181 182 if (conn == null) { 183 return; 184 } 185 186 IBatchStatement batch = statementFactory.createBatchStatement(conn); 187 for (int index = 0; index < sqls.length; index++) { 188 batch.addBatch(sqls[index]); 189 } 190 191 batch.executeBatch(); 192 193 batch.close(); 194 } 195 196 /** 197 * テストファイル名 198 */ 199 private String testDataFile = "DummyData"; 200 201 private DatabaseProperties databaseProperties; 202 private IDataSet dataSet; 203 private StatementFactory statementFactory = new StatementFactory(); 204 } |
DatabaseProperties.java
01 package common; 02 03 import java.io.FileInputStream; 04 import java.io.InputStream; 05 import java.util.Properties; 06 07 /** 08 * @author 09 */ 10 public class DatabaseProperties extends Properties { 11 12 private DatabaseProperties() throws Exception { 13 loadProperties(PROPERTY_FILE_NAME); 14 } 15 16 private DatabaseProperties(String propertiesFilePath) throws Exception { 17 loadProperties(propertiesFilePath); 18 } 19 20 public synchronized static DatabaseProperties create() throws Exception { 21 if (testProoerties == null) testProoerties = new DatabaseProperties(); 22 return testProoerties; 23 } 24 25 public synchronized static DatabaseProperties create(String propertiesFilePath) throws Exception { 26 if (testProoerties == null) testProoerties = new DatabaseProperties(propertiesFilePath); 27 return testProoerties; 28 } 29 30 public String getDriverClassName() { 31 return getProperty("driverClass", "oracle.jdbc.driver.OracleDriver"); 32 } 33 34 public String getDatabaseUrl() { 35 return getProperty("database.Url", "jdbc:oracle:thin:@localhost:1521:PCS"); 36 } 37 38 public String getDatabaseUserName() { 39 return getProperty("database.userName", ""); 40 } 41 42 public String getDatabasePassword() { 43 return getProperty("database.password", ""); 44 } 45 46 public String getDatabaseSchema() { 47 return getProperty("database.schema", ""); 48 } 49 50 public String getTestDataDirectory() { 51 return getProperty("testData.directory", ""); 52 } 53 54 protected void loadProperties(String fileName) throws Exception { 55 56 InputStream is = ClassLoader.getSystemResourceAsStream(fileName); 57 if (is == null) { 58 is = new FileInputStream(fileName); 59 } 60 load(is); 61 } 62 63 private static final String PROPERTY_FILE_NAME = "TestData.properties"; 64 private static DatabaseProperties testProoerties; 65 } |
また、以下のファイルを参考に「TestData.properties」を作成し、プロジェクトの直下に配置します。
driverClass = oracle.jdbc.driver.OracleDriver
database.Url = jdbc:oracle:thin:@localhost:1521:DJWiki
database.userName = djwiki
database.password = djwiki
database.schema = DJWIKI
testData.directory = D:/wiki
"testData.directory"には、XMLとDTDがあるフォルダを指定してください。
通常JUnitのテストケースを作成する場合は"junit.framework.TestCase"クラスを継承しますが、DBUnitTestCaseを継承してテストケースを作成します。
実行方法はJUnitと同様です。
テストケース内のsetUp()でデータのクリーンInsertを行い、tearDown()でデータの消去を行います。
よって、 テスト終了時にはデータベースのデータは無くなります。
(Exportする際に指定したテーブルのみ。)
|