Метод 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]
: