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