DBUnit の .NET 版を作成する(準備)

実は 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 を使って作成する、という不思議/当たり前なことをやっていきます。

カテゴリー: C#, xUnit パーマリンク