実は java 版の DBUnit は xml からデータを読みに行くし、DBUnit.net は動作的に同じなので、自前の DBUnit を作ります。
名前がダブっているけど、これは後から。
UIDD に則って、最初はテストケースをざっくりと作ります。
こんな風に使えると、マニュアルなしでも使えるかもね、という雰囲気で。
using System; using System.Collections.Generic; using System.Text; using System.Data; using System.Data.SqlClient; using NUnit.Framework; using DBUnit.Framework; namespace Test.DBUnit { [TestFixture] public class TestDBUnit { /// <summary> /// 前処理 /// </summary> [SetUp] public void SetUp() { // コネクションを保持 DB.Connection = new SqlConnection(""); } /// <summary> /// 後処理 /// </summary> [TearDown] public void TearDown() { // テーブルの内容を削除 DB.Clear(); } /// <summary> /// DataTable を使ってテスト /// </summary> [TestCase] public void TestSetUp() { DataTable dt = new DataTable(); dt.TableName = "XProduct"; dt.Columns.Add( new DataColumn("ID", typeof(int) )); dt.Columns.Add( new DataColumn("Name", typeof(string) )); DataRow dr = dt.NewRow(); dr["ID"] = 10; dr["Name"] = "masuda"; dt.Rows.Add(dr); dr = dt.NewRow(); dr["ID"] = 20; dr["Name"] = "tomoaki"; dt.Rows.Add(dr); // 前処理 DB.Insert(dt); DataTable result = new DataTable(); SqlDataAdapter da = new SqlDataAdapter( "SELECT * FROM XProduct", DB.Connection); da.Fill(result); Assert.AreEqual(2, result.Rows.Count); Assert.AreEqual(10, result.Rows[0]["ID"]); Assert.AreEqual("masuda", result.Rows[0]["Name"]); // 後処理 DB.Truncate(dt); } /// <summary> /// 独自のDBUnit.DBTable を使ってテスト /// </summary> [TestCase] public void TestSetup2() { DBTable dt = new DBTable("XProduct"); // デフォルト値を設定 dt.SetDefault( "ID", 0, "Name", "", "Update_at", DateTime.Now); // 設定する列名 dt.AddColumns("ID","Name"); // 行を設定 dt.AddRow(10, "masuda"); dt.AddRow(20, "tomoaki"); // insert を実行 dt.Insert(); // データをクリア dt.Clear(); Assert.AreEqual( 0, dt.Rows.Count ); // データベースから読み込み dt.Select(); Assert.AreEqual(2, dt.Rows.Count); Assert.AreEqual(10, dt[0]["ID"]); Assert.AreEqual("masuda", dt[0]["Name"]); // テーブルの内容を削除 dt.Delete(); } } }
微妙にコードが冗長なのは、.NET v2.0 を対象にしているからです。手元のプロジェクトが v2.0 なのでそれに合わせて作らないと意味がないので、というのが第一の理由。LINQ to SQL とタプルなんかを使えるともう少しマシなコードになると思うのですが、そこは v2.0 がターゲットということで。
TestSetUp のほうでは、既存の DataTable/DataRow を使ってみたパターンです。カラムを作るところがやや面倒なのですが、これだとデフォルト値を入れるのが大変なので、テストケースを作るのが苦労しそうです。
なので、TestSetup2 のように、べたべたな仕様にするのがいいかなと。
所詮 NUnit との組み合わせでテストケースにしか使わないので、分かりやすいほうが良いでしょう。型付の DataTable を作成することも考えたのですが、これは環境依存(というかプロジェクトの方針依存)になりそうなので、DataTable 風に扱います。
これをざっくりとクラスとメソッドを作って、コンパイルが通るようにしたのが下記です。
using System; using System.Collections.Generic; using System.Text; using System.Data; using System.Data.SqlClient; namespace DBUnit.Framework { public class DB { public static SqlConnection Connection; public static void Insert(DataTable dt) { } public static void Delete(DataTable dt) { } public static void Truncate(DataTable dt) { } public static void Clear() { } } public class DBRow { public int Count; public object this[string key] { get { return null; } } } public class DBTable { public string TableName; public List<DBRow> Rows; public DBTable(string name) { this.TableName = name; } public void SetDefault(params object[] ps) { } public void AddColumns(params string[] columns) { } public void AddRow(params object[] rows) { } public void Insert() { } public void Clear() { } public void Select() { } public void Delete() { } public DBRow this[ int index ] { get { return this.Rows[index]; } } } }
そして、DBUnit を NUnit を使って作成する、という不思議/当たり前なことをやっていきます。