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

実は java 版の DBUnit は xml からデータを読みに行くし、DBUnit.net は動作的に同じなので、自前の DBUnit を作ります。
名前がダブっているけど、これは後から。

UIDD に則って、最初はテストケースをざっくりと作ります。
こんな風に使えると、マニュアルなしでも使えるかもね、という雰囲気で。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
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 風に扱います。

これをざっくりとクラスとメソッドを作って、コンパイルが通るようにしたのが下記です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
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 パーマリンク