EntityFramework 5、SQL Server Compact 4、および Xunit を使用していくつかの単体テストをセットアップしようとしています。
ASP MVC アプリをテストしていて、デタッチされたエンティティに対するいくつかの更新操作の動作をテストする必要があるため、別のコンテキスト インスタンスを使用しています。
[Fact, AutoRollback]
public void TestConnection()
{
using (var connection = this.GetDbConnection())
{
using (var context = new MyContext(connection, false))
{
// Do database stuff
}
using (var context = new MyContext(connection, false))
{
// Do database stuff
}
}
}
public DbConnection GetDbConnection()
{
string dataSource = "|DataDirectory|\\MyDb.sdf";
var sqlBuilder = new SqlCeConnectionStringBuilder();
sqlBuilder.DataSource = dataSource;
return new SqlCeConnection(sqlBuilder.ToString());
}
これにより、次のエラーが表示されます。
System.Data.EntityException : The underlying provider failed on Open.
System.InvalidOperationException : The connection object can not be enlisted in transaction scope.
TransactionScope 内で複数の DbContext インスタンスを開くことができないことはわかっています (これはおそらく、メソッドに FallbackAttribute を配置したときに Xunit が行うことです)。そのため、事前に接続を作成しています。
自分で接続を開こうとしても、まだ機能しません。
using (var connection = this.GetDbConnection())
{
connection.Open();
using (var context = new MyContext(connection, false))
{
次の例外が発生します。
System.ArgumentException : EntityConnection can only be constructed with a closed DbConnection.
その問題を解決する方法を知っている人はいますか?
編集
Db を処理するテスト クラスは、データベースが次のように初期化される "DomainFactsBase" を拡張します。
public DomainFactsBase()
{
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<MyContext>());
using (var context = new MyContext(GetDbConnection(), true))
context.Database.Initialize(false);
}
編集
コンテキスト インスタンスを 1 つだけ作成すると、自動ロールバックを使用してテストを正常に実行できます。これは、この記事の指示に従って実行されました。私は拡張メソッドを持っています:
public static void OpenConnection(this DbContext context)
{
((IObjectContextAdapter)context).ObjectContext.Connection.Open();
}
そして、テストでコンテキストを作成した直後に呼び出します。
[Fact, AutoRollback]
public void SomeFact()
{
using (var context = new MyContext())
{
context.OpenConnection();
// Do stuff
}
}
問題なく動作します。最初に例示したように、(AutoRollback を有効にして) 同じファクトでコンテキストを複数回開こうとすると発生します。