Menu

FrontPage

Eclipseプラグイン
Eclipse小技集
リファクタリング講座
テスティングフレームワーク JUnit
MSDEについて



The 20 newest affair
2010-09-092010-09-082010-09-072010-09-062010-09-012010-08-312010-08-272010-08-242010-08-232010-08-172010-08-162010-07-302010-07-212010-07-132010-06-272010-06-182010-06-172010-06-16

dbUnit使用方法 ~ Flat XML DataSet編


データベースのデータをXMLに出力し、そのXMLのデータを使ったテスト方法です。
テストメソッドが実行されるたびにデータを削除し出力したXMLのデータをInsertするので、毎回同じデータでテストが実行できます。
InsertやDeleteのテスト後のSelectのテストでも結果が変わったりすることはありません。


必要ファイル


exml.zip
dtdparser.zip

上記2つのファイルを解凍したフォルダ
  • 「exml」
  • 「dtdparser」
を適当な場所へ配置する。

*これはXMLデータ書き出し用です。dbUnitの設定はdbUnit設定方法で。


DataExport.java


データベースからデータを取得し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[] argsthrows 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」フォルダ内にある
  • exml.jar
  • dtdparser.jar
に対してパスを通しておきます。


●設定が必要な箇所
  • 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 sqlthrows 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[] sqlsthrows 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 sqlthrows 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[] sqlsthrows 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 connthrows 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 connthrows 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 fileNamethrows 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 sqlthrows 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[] sqlsthrows 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 propertiesFilePaththrows Exception {
17         loadProperties(propertiesFilePath);
18     }
19     
20     public synchronized static DatabaseProperties create() throws Exception {
21         if (testProoerties == nulltestProoerties = new DatabaseProperties();
22         return testProoerties;
23     }
24     
25     public synchronized static DatabaseProperties create(String propertiesFilePaththrows Exception {
26         if (testProoerties == nulltestProoerties = 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 fileNamethrows 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する際に指定したテーブルのみ。)


Attached File: [Attached File All List]

Lastmodified: 2010-06-15 (火) 22:42:07 (85d)