Linq-to-Entities(EF4)とLinq-to-Objectsの潜在的な違いにより、実際のデータベースを使用してクエリクラスがデータを取得する必要がありますEFから正しく。 SQL CE 4はこれには最適なツールだと思われますが、いくつかの問題に直面しています。これらのテストはMsTestを使用しています。Sql CE 4データベースを機能テストに使用する方法
問題は、データベースがモデル変更のために再作成されない場合、各テスト後にデータを削除せずにデータベースにデータが追加され続けることです。これにより、テストで競合が発生する可能性があり、クエリより多くのデータが返されます。
最初の考えはメソッドのTransactionScope
を初期化し、トランザクションをTestCleanup
に配置することでした。残念ながら、SQL CE4はトランザクションをサポートしていません。
私の次のアイデアは、TestCleanup
のデータベースをFile.Delete()
コールで削除することでした。残念ながら、これは、最初のテストが実行された後、最初のテストのTestCleanup
がデータベースを削除するようだが、最初のテスト後のすべてのテストはデータベースを再作成しないように見えるので、データベースファイルが見つかりません。
私は私のテストクラスのClassInitialize
とClassCleanup
にTestInitialize
とTestCleanup
タグを変更しようとしましたが、それは前ClassInitialize
に実行されているため、テストにNullReferenceException
でエラーが発生した(あるいはそれが表示されます。ClassInitialize
はので、多分それはだ基底クラスでありますそれを引き起こす)。
Sql CE4をテストに効果的に使用する方法がなくなりました。誰か良いアイデアはありますか?
編集:私は解決策を見つけ出しました。私のEFユニットのテスト基底クラスでは、自分のデータコンテキストの新しいインスタンスを開始し、次に
context.Database.Delete()
と
context.Database.Create()
を呼び出します。ユニットテストは少し遅くなるが、今、私はユニットテスト効果的に実際のデータベース
最終編集使用することができます前後にMicrosoftと一部のメールの後を、それが
TransactionScope
sが今SQLCEで許可されていることが判明しますSqlCEの最新リリースでリリースされました。ただし、EF4を使用している場合は、トランザクションを開始する前に明示的にデータベース接続を開く必要があるという点でいくつかの制限があります。あなたの
TestInitialize
あなたが次のことを行う必要がありますで
[TestMethod]
public void My_SqlCeScenario()
{
using (var context = new MySQLCeModelContext()) //ß derived from DbContext
{
ObjectContext objctx = ((IObjectContextAdapter)context).ObjectContext;
objctx.Connection.Open(); //ß Open your connection explicitly
using (TransactionScope tx = new TransactionScope())
{
var product = new Product() { Name = "Vegemite" };
context.Products.Add(product);
context.SaveChanges();
}
objctx.Connection.Close(); //ß close it when done!
}
}
もちろん、SQL CEはトランザクションをサポートしていますが、TransactionScopeを使用するのは非常に間違った方法です。通常は、Connectionオブジェクトを介して行います。 – leppie
あなたが 'SaveChanges()'を呼ばないことを意味しない限り、 'TransactionScope'を持たないEF4エンティティではどうしたらいいのか分かりません。つまり、テストは有効なテストではありません。 – KallDrexx
Sql CEでデータをシードする方法の例を挙げることができますか?私はEF6を使用して、それをテストしたいと思っています。 –