Метод ExecutelnATransaction() выполняется с применением одиночного экземпляра ApplicationDbContext. Метод ExecutelnASharedTransaction() позволяет нескольким экземплярам ApplicationDbContext совместно использовать транзакцию. Вы узнаете больше об упомянутых методах позже в главе, а пока добавьте в свой класс BaseTest следующий код:
protected void ExecuteInATransaction(Action actionToExecute)
{
var strategy = Context.Database.CreateExecutionStrategy();
strategy.Execute(() =>
{
using var trans = Context.Database.BeginTransaction();
actionToExecute();
trans.Rollback();
});
}
protected void ExecuteInASharedTransaction(Action
actionToExecute)
{
var strategy = Context.Database.CreateExecutionStrategy();
strategy.Execute(() =>
{
using IDbContextTransaction trans =
Context.Database.BeginTransaction(IsolationLevel.ReadUncommitted);
actionToExecute(trans);
trans.Rollback();
});
}
Добавление класса тестовой оснастки EnsureAutoLotDatabase
Инфраструктура тестирования xUnit предоставляет механизм, который позволяет запускать код до прогона любого теста (называется настройкой IClassFixture, должны будут выполнять код конструктора типа Т (т.е. TestFixtureClass) до прогона любого теста и код метода Dispose() после завершения всех тестов.
Создайте в каталоге Base новый файл класса по имени EnsureAutoLotDatabaseTestFixture.cs и реализуйте интерфейс IDisposable. Сделайте класс открытым и запечатанным, а также добавьте показанные далее операторы using:
using System;
using AutoLot.Dal.Initialization;
namespace AutoLot.Dal.Tests.Base
{
public sealed class EnsureAutoLotDatabaseTestFixture : IDisposable
{
}
}
В конструкторе понадобится создать экземпляр реализации IConfiguration и с его помощью создать экземпляр ApplicationDbContext. Затем нужно вызвать метод ClearAndReseedDatabase() класса SampleDatalnitializer и в заключение освободить экземпляр контекста. В приводимых здесь примерах метод Dispose() не обязан выполнять какую-то работу (но должен присутствовать для соответствия шаблону с интерфейсом IDisposable). Вот как выглядит конструктор и метод Dispose():
public EnsureAutoLotDatabaseTestFixture()
{
var configuration = TestHelpers.GetConfiguration();
var context = TestHelpers.GetContext(configuration);
SampleDataInitializer.ClearAndReseedDatabase(context);
context.Dispose();
}
public void Dispose()
{
}
Добавление классов интеграционных тестов
Теперь необходимо создать классы, которые будут поддерживать автоматизированные тесты. Такие классы называют AutoLot.Dal. Tests новый каталог по имени IntegrationTests и поместите в него четыре файла с именами CarTests.cs, CustomerTests.cs, MakeTests.cs и OrderTests.cs.
В зависимости от возможностей средства запуска тестов тесты xUnit выполняются последовательно внутри тестовой оснастки (класса), но параллельно во всех тестовых оснастках (классах). Это может оказаться проблематичным при прогоне интеграционных тестов, взаимодействующих с единственной базой данных. Выполнение можно сделать последовательным для всех тестовых оснасток, добавив их в одну и ту же тестовую коллекцию. Тестовые коллекции определяются по имени с применением атрибута [Collection] к классу. Поместите перед всеми четырьмя классами следующий атрибут [Collection]: