Модульные тесты Fluent Migrator: удержание соединения

Я пытаюсь создать проект модульного тестирования, чтобы убедиться, что все миграции, сделанные в проекте, будут успешно разрешать миграции вверх и вниз.

Я пытаюсь добиться этого, создав для этого два модульных теста.

Настраивать:

  • 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 в базе данных показывает, что в базе данных есть «спящий» процесс, который «ОЖИДАЕТ КОМАНДУ», оставленный в базе данных. Это означает, что TearDown моего теста не сможет удалить временную базу данных, поскольку «база данных используется».

Просматривая бегун, я не могу найти способ закрыть это соединение, я пытался изменить тайм-ауты всех задействованных компонентов, а также пытался отключить «пул» в строке подключения, но ни один из них не работал.

Есть ли способ закрыть это соединение или убедиться, что оно закрыто?

Спасибо


person Jono_2007    schedule 04.08.2015    source источник


Ответы (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);
}

Я также предполагаю, что неутилизация процессора является причиной зависания соединения.

person FireAlkazar    schedule 04.08.2015
comment
Это сработало отлично, спасибо. Я немного раздражен на себя, я не заметил IDisposable, должен был догадаться с ним, используя фабрику. - person Jono_2007; 05.08.2015