2016-02-16 6 views
2

Использование xUnit и TestServer от Microsoft.AspNet.TestHost, как я могу обернуть каждый тест в транзакции базы данных, которая может быть отброшена после теста?Как выполнить интеграционные тесты, которые используют TestServer в транзакции базы данных?

Вот как я создаю TestServer:

TestServer = new TestServer(TestServer.CreateBuilder() 
    .UseStartup<Startup>()); 

Startup, который ссылается есть Startup из проекта веб-приложения. В методе ConfigureServices в этом классе Startup добавить EF, как это:

services.AddEntityFramework() 
    .AddSqlServer() 
    .AddDbContext<TrailsDbContext>(options => options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"])); 

я мог вытащить DbContext обратно услуг и сохранить статическую ссылку на Startup класса, но это кажется довольно Hacky. Есть ли способ создать экземпляр DbContext, где я создаю TestServer и как-то использовать веб-приложение, а не тот, что в классе Startup?

Редактировать: Я попытался создать экземпляр другого экземпляра DbContext, где создаю TestServer и используя этот контекст для удаления и воссоздания базы данных перед каждым тестом, но это добавляет примерно 10 секунд к времени выполнения каждого теста.

ответ

1

Некоторые рекомендации: самый простой подход заключается в том, чтобы уничтожить тестовую базу данных в конце и воссоздать для каждого тестового прогона. Это не обеспечивает затяжной тест-тест.

Но поскольку вы спросили, как это сделать, вы можете расширить Xunit. Xunit позволяет определить пользовательские тестовые примеры и тестовые ролики. Полный ответ трудно включить в ответ SO. Простейшее решение использует внешние транзакции. (Danger! Ambient транзакции могут быть сложными.) Xunit имеет образец для пользовательского атрибута BeforeAfterTestAttribute, который откатывает транзакцию. https://github.com/xunit/samples.xunit/tree/master/AutoRollbackExample. Чтобы использовать внешние транзакции, отключите стандартную настройку EF, которая срабатывает, если присутствуют внешние транзакции. (optionsBuilder.UseSqlServer().SuppressAmbientTransactionWarning()).

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

Кроме того, EF docs предоставляет образец использования поставщика InMemory для тестирования. Вы можете найти это полезным. "Testing In Memory : EF Core Docs"