担当プロジェクトの大きな修正のために、今週はずっとテストコードを書いています。ゴリゴリと。でも、いい加減飽きてきました。複数のデータベースの、これまた複数のテーブルを利用するので、テストデータを用意するのが大変。もうやめて!id:griefworker のライフはゼロよ!
さて、前に「テストデータの追加・削除を行うなら LINQ to SQL を使うと便利」みたいな内容の記事を書きました。
LINQ to SQL を使ってテストデータの作成・削除を楽にする - present
この方法だと、データベースに追加したテストデータをテストクラスが保持するので、コードが長くなりがちです。そこで、私は次のようなヘルパークラスを利用しています。
public class DataContextTestHelper<TDataContext> where TDataContext : System.Data.Linq.DataContext, new() { public TDataContext Context { get; private set; } private List<object> _entities; public DataContextTestHelper() : this(new TDataContext()) { } public DataContextTestHelper(TDataContext context) { _entities = new List<object>(); Context = context; } // データベースにエンティティを登録する public void Setup(params object[] entities) { if (0 < entities.Length) { foreach (var entity in entities) { Context.GetTable(entity.GetType()) .InsertOnSubmit(entity); } // エンティティをキャッシュする _entities.AddRange(entities); // データベースに変更を反映 using (TransactionScope ts = new TransactionScope()) { Context.SubmitChanges(); ts.Complete(); } } } // データベースからエンティティを削除する public void Cleanup() { if (0 < _entities.Count) { foreach (var entity in _entities) { Context.GetTable(entity.GetType()) .DeleteOnSubmit(entity); } using (TransactionScope ts = new TransactionScope()) { Context.SubmitChanges(); ts.Complete(); } } } }
使い方は次の通りです。
private static DataContextTestHelper<FooDataContext> _helper = new DataContextTestHelper<FooDataContext>(); [ClassInitialize()] public static void MyClassInitialize(TestContext testContext) { // テストデータ作成 Foo testData = new Foo(); testData.Code1 = 9999; testData.Code2 = 999; testData.Name = "TEST"; // テストデータをデータベースに保存 _helper.Setup(testData); } [ClassCleanup()] public static void MyClassCleanup() { // テストデータをデータベースから削除 _helper.Cleanup(); }
ヘルパーが内部にテストデータを保持しているので、テストデータをテストクラスが保持しなくて済みます。削除もメソッド呼び出しで一発。おかげでコード量もだいぶ減ります。地味に便利。
……用意するテストデータの量は変わらないですけどね。