#freeze
* [[DbUnit]]
DB使ったテストツールです。 テストデータをDBにほうりこんだり、メソッド実行後に正しく入っているかの検証をしたりできます。放り込むデータはXMLやExcelが使用できます。
#contents

** 環境
ではhttp://dbunit.sourceforge.net/のhttp://sourceforge.net/project/showfiles.php?group_id=47439&release_id=242511より2.2をダウンロードしました。(2007/09/08) 展開後、dbunit-2.2.jarをプロジェクトのライブラリに追加しておきましょう。ここではEclipseでのプロジェクトをさしています。CompositeTable
投入するデータを用意しておきましょう。~
table001_s.xml~
 <?xml version='1.0' encoding="EUC-JP"?>
 <dataset>
   <table001 uname="admin001" nokokyaku="hoge" />
   <table001 uname="admin002" nokokyaku="hoge2" />
 </dataset>
また実行結果のxmlも用意しておきます。~
table001_e.xml
 <?xml version='1.0' encoding="EUC-JP"?>
 <dataset>
   <table001 uname="admin001" nokokyaku="hoge" />
   <table001 uname="admin002" nokokyaku="hoge2" />
   <table001 uname="admin003" nokokyaku="hoge3" />
 </dataset>
さらに1行比較用のxmlも用意します。このあたりは必要に応じて作成します。
table001_e1.xml
 <?xml version='1.0' encoding="EUC-JP"?>
 <dataset>
   <table001 uname="admin003" nokokyaku="hoge3" />
 </dataset>
形式は
 <dataset>
   <テーブル名 カラム名="値"  ..../>
   <テーブル名 カラム名="値"  ..../>
      ・
      ・
 </dataset>
てな感じです。ではこれをプロジェクトのトップにおいておいて、テストクラスを作成します。ちなみにデータに改行がある場合とかは、
 koumoku="いいいいいい&#13;&#10;うううううううう&#13;&#10;ええええええええ"
とかします。
 &#10;
だけにするかは環境の文字コードによります。
ここでは、データを一行挿入し、dbの中身がtable001_e.xmlと同じになっているかを検証しています。~
またSQL文から取得したデータと合致するかどうかも比較します。
Dbtest.java
 package com.example.tests;
 
 import java.io.FileReader;
 import java.sql.Connection;
 import java.sql.DriverManager;
 
 import org.dbunit.Assertion;
 import org.dbunit.DatabaseTestCase;
 import org.dbunit.database.DatabaseConnection;
 import org.dbunit.database.IDatabaseConnection;
 import org.dbunit.dataset.IDataSet;
 import org.dbunit.dataset.ITable;
 import org.dbunit.dataset.SortedTable;
 import org.dbunit.dataset.xml.FlatXmlDataSet;
 
 public class Dbtest extends DatabaseTestCase {
	private static final String driver = "org.gjt.mm.mysql.Driver";
	private static final String url = "jdbc:mysql://192.168.1.1:3306/db";
	private static final String user = "hogeuser";
	private static final String password = "hogepass";
	private Connection conn;
 
	public Dbtest(String name) {
		super(name);
	}
 
	// データベースに接続
	protected IDatabaseConnection getConnection() throws Exception {
		Class.forName(driver);
		conn = DriverManager.getConnection(url, user, password);
		// String schema = conn.getMetaData().getUserName();
		//これにするとMySQLの場合、SQLエラーで落ちた。
		//スキーマ指定についてはデータベースに依存する
		// return new DatabaseConnection(conn, schema);
		return new DatabaseConnection(conn);
	}
 
	// 初期化データをXMLファイルよりインポート
	protected IDataSet getDataSet() throws Exception {
		return new FlatXmlDataSet(new FileReader("table001_s.xml"));
	}
 
	// テストケースの記述
	public void testExecuteInsert() throws Exception {
 		//すでにコネクションはクローズされている。
		getConnection();
		// InsertSampleインスタンスを生成し、table001テーブルにレコードをインサート
		InsertSample sample = new InsertSample(conn);
		sample.execeuteInsert("admin003", "hoge3");
 
		// インサート実行後のsampleテーブルのレコードを取得
		IDataSet actualDataSet = getConnection().createDataSet();
		ITable table = actualDataSet.getTable("table001");
		//取得したデータをソートしておく。
		ITable actualSample = new SortedTable(table, new String[] { "UNAME",
				"NOKOKYAKU" });
 
		// インサート後のsampleテーブルの予測結果をXMLファイルから取得
		ITable expectedSample = new FlatXmlDataSet(
				new FileReader("table001_e.xml")).getTable("table001");
		// 実際の結果と予測した結果の比較 このAssertionはorg.dbunit
		Assertion.assertEquals(expectedSample, actualSample);
 
		// 条件を指定して比較
		String sql = "select * from table001 where uname = 'admin003'";
		ITable actualTable = getConnection().createQueryTable("actual", sql);
		ITable expectedSample2 = new FlatXmlDataSet(new FileReader(
				"table001_e1.xml")).getTable("xoops_xy003");
		// 実際の結果と予測した結果の比較
		org.dbunit.Assertion.assertEquals(expectedSample2, actualTable);
 
		// 項目比較
		sql = "select * from table001 where uname = 'admin003'";
		actualTable = getConnection().createQueryTable("actual", sql);
		assertEquals("admin003", (actualTable.getValue(0, "uname").toString()));
 
		// ちなみにactualTable.getRowCount()で行数取得
	}
 }

InsertSample.java
 package com.example.tests;
 
 import java.sql.Connection;
 import java.sql.Statement;
 
 import junit.framework.TestCase;
 
 public class InsertSample extends TestCase {
	Connection conn;
 
	public InsertSample(Connection _conn) {
		conn = _conn;
	}
 
	public void execeuteInsert(String id, String name) {
		try {
			Statement stmt = conn.createStatement();
 
			// 引数で受け取ったidとnameを使ってテーブルに新規レコードを挿入
			String sql = "INSERT INTO table001(uname, nokokyaku) VALUES('"
					+ id + "', '" + name + "')";
			stmt.execute(sql);
 
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
 }

ではテストデータをXMLではなくExcelで作成する場合はどうするのでしょうか。まず
 ワークシート名 →テーブル名
 1行目     →テーブルのカラム名
 2行目以降   →データを記述。
として作成します。またhttp://poi.apache.org/のdownloadよりpoi-bin-3.0.1-FINAL-20070705.zipをダウンロードして展開後、
poi-3.0.1-FINAL-20070705.jarをライブラリに追加しておきます。あとは上記のサンプルで、
 FlatXmlDataSet(new FileReader("table001_s.xml")); 
を
 XlsDataSet(new FileInputStream("table001_s.xml"));
と変更していけばOKです。
** TIPS
*** 列を制限して取得
 ITable filteredTable = DefaultColumnFilter.excludedColumnsTable(
        getConnection().getDataSet().getTable("テーブル名"),
        new String[]{"列名1", "列名2"});

** MEMO
***CompositeTable
 Table compositTable = new CompositeTable(
 expectTable.getTableMetaData(), resultTable);
期待されたxmlに書いていないカラムを対象外として比較できるTableを取得できる。
***DefaultColumnFilter
** リンク
***[[DBUnitにさわる>http://muimi.com/j/test/dbunit/]]
わかりやすいサンプルがあります。
***[[STACK DbUnit>http://www.stackasterisk.jp/tech/java/dbunit01_01.jsp]]
上記同様わかりやすいサンプルがあります。
***[[TECHSCORE DBUnit>http://www.techscore.com/tech/Others/DBUnit/index.html]]
上記同様わかりやすいサンプルがあります。
***[[ dbUnit使用方法 ~ XLS DataSet編>http://works.dgic.co.jp/djwiki/Viewpage.do?pid=@6462556E6974E4BDBFE794A8E696B9E6B39520EFBD9E20584C532044617461536574E7B7A8]]
図解入りで丁寧な説明があります。
***[[DbUnit - オープンソースでいきまっしょい>http://wiki.opensquare.jp/?DbUnit]]
いろいろとサンプルがあり、参考になります。

** TODO
-Excelに出力すると文字化け~
XlsDataSet.writeではくと文字化けしてしまいます。DBがEUCなんですが、どこで変換してやろうか。
** 参考書籍

** コメント
-#comment

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS