2012-03-28 11 views
5

質問とコードはCode First Entity Framework Unit Test Examplesのブログ記事に基づいています。私はSQL Compact 4.0を使用しています。そのため、私の単体テストは、実際のデータを使って実際のデータベースに対して実行されています。Entity Frameworkコード1:単体テストのためにデータベースをシードする方法

テーブルの一部にデフォルト値を設定したいのですが、単体テストを実行しているときにデータを追加してデフォルト値の一部を更新したいとします。

データベースにデフォルト値を設定するカスタムInitializerクラスを作成しました。

public class NerdDinnersInitializer : DropCreateDatabaseIfModelChanges<NerdDinners> 
{ 
    protected override void Seed(NerdDinners context) 
    { 
     var dinners = new List<Dinner> 
          { 
           new Dinner() 
            { 
             Title = "Dinner with the Queen", 
             Address = "Buckingham Palace", 
             EventDate = DateTime.Now, 
             HostedBy = "Liz and Phil", 
             Country = "England" 
            } 
          }; 

     dinners.ForEach(d => context.Dinners.Add(d)); 

     context.SaveChanges(); 
    } 
} 

public class NerdDinnersInitializerForTesting : NerdDinnersInitializer 
{ 
    protected override void Seed(NerdDinners context) 
    { 
     base.Seed(context); 

     var dinner = context.Dinners.Where(d => d.Country == "England").Single(); 
     dinner.Country = "Ireland"; 

     context.SaveChanges(); 
    } 
} 

は、私も私のユニットテストの基本クラスを使用するようにテスト・データベースを初期化します。私のユニットテストのために私は、テストの特定の播種および/または修正を行う最初のものを継承する別のカスタム初期化子を作成しました私はsavedDinnerをフェッチLINQのクエリが失敗したとテストを実行すると

[TestClass] 
public class UnitTest1 : TestBase 
{ 
    [TestMethod] 
    public void TestMethod1() 
    { 
     var dinner = new Dinner() 
          { 
           Title = "Dinner with Sam", 
           Address = "Home", 
           EventDate = DateTime.Now, 
           HostedBy = "The wife", 
           Country = "Italy" 
          }; 

     DataContext.Dinners.Add(dinner); 
     DataContext.SaveChanges(); 

     var savedDinner = (from d in DataContext.Dinners 
          where d.DinnerId == dinner.DinnerId 
          select d).Single(); 

     Assert.AreEqual(dinner.Address, savedDinner.Address); 
    } 
} 

:そう:

[TestClass] 
public abstract class TestBase 
{ 
    protected const string DbFile = "test.sdf"; 
    protected const string Password = "1234567890"; 
    protected NerdDinners DataContext; 

    [TestInitialize] 
    public void InitTest() 
    { 
     Database.DefaultConnectionFactory = new SqlCeConnectionFactory("System.Data.SqlServerCe.4.0", "", 
       string.Format("Data Source=\"{0}\";Password={1}", DbFile, Password)); 
     Database.SetInitializer(new NerdDinnersInitializerForTesting()); 

     DataContext = new NerdDinners(); 
     DataContext.Database.Initialize(true); 
    } 

    [TestCleanup] 
    public void CleanupTest() 
    { 
     DataContext.Dispose(); 

     if (File.Exists(DbFile)) 
     { 
      File.Delete(DbFile); 
     } 
    } 
} 

実際のユニットテストは、次のようになります"ObjectContextインスタンスは削除されており、接続が必要な操作には使用できなくなりました。"例外。なぜ私はうまくいかない。

ここで私が受け入れていることは受け入れ可能なパターンなのでしょうか?これがなぜ機能しないのか誰にも分かりますか?

ありがとうございました。

+0

オブジェクトコンテキストが破棄される理由はわかりません。ユニットテストをデバッグして、savechangesメソッドにブレークポイントを設定し、datacontextがnullでないかどうか確認できますか?次の行にsetpし、datacontextがnullであるかどうかを確認してください。 – daryal

+0

こんにちはDaryal、どちらの場合でもdatacontextはnullではありません。 DataContext.SaveChanges(); datacontextがnullではないにもかかわらず失敗した後のLinqクエリです。 –

+0

問題なしでDataContext.Dinnersをforeachできます。 DataContextではなく、ObjectContextが破棄されているというエラーが表示されます。 ObjectContextがLinqクエリのDataContextと同じかどうかわかりません。とにかく、次のようにしてください:var initDb = new SvDataContext(); initDb.Database.Initialize(true); DataContext =新しいSvDataContext();私のInitTestメソッドで問題を解決します。 –

答えて

3

私は今朝同様の問題に遭遇しました。この問題は、シードメソッドのwhere句によって発生します。 (今のところ)これを回避するには、これを書き換えている:

効率的ではありません(すべてのオブジェクトがデータベースから取得され、フィルタリングがメモリ内で行われます)が
var dinner = context.Dinners.ToList().Where(d => d.Country == "England").Single(); 

、それは私のユニットテストでObjectDisposedExceptionを解決しました。私の場合、私はいくつかのオブジェクトしか持っていないので、私は今のところそれと一緒に暮らすことができます。

+0

あなたの答えをありがとうJos。どのように問題を特定しましたか? –

+1

問題はIoCの設定によって引き起こされたと考えていたので、DisposedExceptionのためにかなり時間がかかりました。私はよく知っていたはずだったが、私は何も変えなかったし、前に働いていた。私は実用的なシナリオを持っていましたが、問題が発生しなくなるまでシードコードを新しく導入したコードにコメントして、追加のモデル(where句も導入しました)でシードコードを修正しました。 where句コードのコメントを外し、例外が戻ってきました。クローズドソースフレームワークがダウンさせた場合のシンプルで効果的なエラートレース –

関連する問題