4

プロジェクトで行われたすべての移行で上下の移行が正常に許可されるように、単体テスト プロジェクトを作成しようとしています。

これを行うために2つの単体テストを作成することで、これを達成しようとしています。

設定:

  • NUnit
  • EntityFramework
  • LocalDB FluentMigrator とランナー

これは、単体テストのセットアップです。これらすべてのテストが使用する LocalDb データベース (v11) へのリンクである接続文字列があります。

[TestFixture]
public class MigrationTestHandler
{
    private string ConnectionString
    {
        get
        {
            return ConfigurationManager.ConnectionStrings["MigrationDatabase"].ConnectionString;
        }
    }

    [SetUp]
    public void SetUp()
    {
        var blankContext = new DbContext(ConnectionString);
        blankContext.Database.Delete();
        blankContext.Database.Create();
    }

    [TearDown]
    public void TearDown()
    {
        var blankContext = new DbContext(ConnectionString);
        blankContext.Database.Delete();
    }

    [Test]
    public void CanUpgradeDatabase()
    {
        var migrator = new MigrationRunnerHandler(ConnectionString);
        migrator.Migrate(runner => runner.MigrateUp());
    }

    [Test]
    public void CanRollbackDatabase()
    {
        var migrator = new MigrationRunnerHandler(ConnectionString);
        migrator.Migrate(runner => runner.MigrateUp());
        migrator.Migrate(runner => runner.Rollback(int.MaxValue));
    }
}

これは、すべての移行を呼び出すために使用する移行ランナー ハンドラ クラスです。

public class MigrationRunnerHandler
{
    private readonly string _connectionString;
    private FluentMigrator.Runner.MigrationRunner Runner { get; set; }

    public MigrationRunnerHandler(string connectionString)
    {
        _connectionString = connectionString;
    }

    private class MigrationOptions : IMigrationProcessorOptions
    {
        public bool PreviewOnly { get; set; }
        public int Timeout { get; set; }
        public string ProviderSwitches { get; set; }
    }

    public void Migrate(Action<IMigrationRunner> runnerAction)
    {
        var factory = new SqlServer2008ProcessorFactory();
        var assembly = Assembly.GetExecutingAssembly();

        var announcer = new TextWriterAnnouncer(s => Console.Write(s));
        var migrationContext = new RunnerContext(announcer)
        {
            TransactionPerSession = true,
        };
        var processor = factory.Create(_connectionString, announcer, new MigrationOptions 
        { 
            PreviewOnly = false,
            Timeout = 5
        });
        Runner = new FluentMigrator.Runner.MigrationRunner(assembly, migrationContext, processor);

        runnerAction(Runner);
    }
}

問題は、テストのティアダウン時に、FluentMigrator がデータベースへの接続を保持しているように見えることです。データベースで sp_who を実行すると、データベースに残っている「AWAITING COMMAND」である「スリープ」プロセスがデータベースにあることが示されます。これは、「データベースが使用中」であるため、テストの TearDown が一時データベースの削除に失敗することを意味します。

ランナーを調べると、この接続を閉じる方法が見つからないようです。関連するすべてのコンポーネントのタイムアウトを変更しようとし、接続文字列で「プーリング」をオフにしようとしましたが、どちらも機能しませんでした。

この接続を閉じる方法、または確実に閉じる方法はありますか?

ありがとう

4

1 に答える 1

1

IMigrationProcessor は IDisposable を実装しているため、次のように使用する必要があります。

using(var processor = factory.Create(_connectionString, announcer, new MigrationOptions 
{ 
    PreviewOnly = false,
    Timeout = 5
}))
{
    Runner = new FluentMigrator.Runner.MigrationRunner(assembly, migrationContext, processor);

    runnerAction(Runner);
}

また、プロセッサを破棄しないことが接続がハングする理由だと思います。

于 2015-08-04T22:20:20.743 に答える