質問とコードは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インスタンスは削除されており、接続が必要な操作には使用できなくなりました。"例外。なぜ私はうまくいかない。
ここで私が受け入れていることは受け入れ可能なパターンなのでしょうか?これがなぜ機能しないのか誰にも分かりますか?
ありがとうございました。
オブジェクトコンテキストが破棄される理由はわかりません。ユニットテストをデバッグして、savechangesメソッドにブレークポイントを設定し、datacontextがnullでないかどうか確認できますか?次の行にsetpし、datacontextがnullであるかどうかを確認してください。 – daryal
こんにちはDaryal、どちらの場合でもdatacontextはnullではありません。 DataContext.SaveChanges(); datacontextがnullではないにもかかわらず失敗した後のLinqクエリです。 –
問題なしでDataContext.Dinnersをforeachできます。 DataContextではなく、ObjectContextが破棄されているというエラーが表示されます。 ObjectContextがLinqクエリのDataContextと同じかどうかわかりません。とにかく、次のようにしてください:var initDb = new SvDataContext(); initDb.Database.Initialize(true); DataContext =新しいSvDataContext();私のInitTestメソッドで問題を解決します。 –