DbUnit

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

環境

では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にさわる

わかりやすいサンプルがあります。

STACK DbUnit

上記同様わかりやすいサンプルがあります。

TECHSCORE DBUnit

上記同様わかりやすいサンプルがあります。

dbUnit使用方法 ~ XLS DataSet編

図解入りで丁寧な説明があります。

DbUnit - オープンソースでいきまっしょい

いろいろとサンプルがあり、参考になります。

TODO

  • Excelに出力すると文字化け
    XlsDataSet?.writeではくと文字化けしてしまいます。DBがEUCなんですが、どこで変換してやろうか。

参考書籍

コメント

  • #comment

トップ   編集 凍結解除 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2007-09-12 (水) 02:22:00 (6091d)