Язык программирования C#9 и платформа .NET5
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<IDbContextTransaction>actionToExecute){var strategy = Context.Database.CreateExecutionStrategy();strategy.Execute(() =>{using IDbContextTransaction trans =Context.Database.BeginTransaction(IsolationLevel.ReadUncommitted);actionToExecute(trans);trans.Rollback();});}Добавление класса тестовой оснастки EnsureAutoLotDatabase
Инфраструктура тестирования xUnit предоставляет механизм, который позволяет запускать код до прогона любого теста (называется настройкой оснастки) и после прогона всех тестов (называется освобождением оснастки). Обычно поступать так не рекомендуется, но в рассматриваемом случае желательно удостовериться, что база данных создана и загружена данными до прогона любого теста, а не до прогона каждого теста. Классы тестов, которые реализуют
, должны будут выполнять код конструктора типаIClassFixture<T> where Т: TestFixtureClass(т.е.Т) до прогона любого теста и код методаTestFixtureClassпосле завершения всех тестов.Dispose()Создайте в каталоге
новый файл класса по имениBaseи реализуйте интерфейсEnsureAutoLotDatabaseTestFixture.cs. Сделайте класс открытым и запечатанным, а также добавьте показанные далее операторыIDisposable:usingusing 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(){}Добавление классов интеграционных тестов
Теперь необходимо создать классы, которые будут поддерживать автоматизированные тесты. Такие классы называют тестовыми оснастками. Добавьте в проект
. Tests новый каталог по имениAutoLot.Dalи поместите в него четыре файла с именамиIntegrationTests,CarTests.cs,CustomerTests.csиMakeTests.cs.OrderTests.csВ зависимости от возможностей средства запуска тестов тесты xUnit выполняются последовательно внутри тестовой оснастки (класса), но параллельно во всех тестовых оснастках (классах). Это может оказаться проблематичным при прогоне интеграционных тестов, взаимодействующих с единственной базой данных. Выполнение можно сделать последовательным для всех тестовых оснасток, добавив их в одну и ту же тестовую коллекцию. Тестовые коллекции определяются по имени с применением атрибута
к классу. Поместите перед всеми четырьмя классами следующий атрибут[Collection]:[Collection][Collection("Integration Tests")]Унаследуйте все четыре класса от
, реализуйте интерфейсBaseTestи приведите операторыIClassFixtureк показанному далее виду:using// CarTests.csusing System.Collections.Generic;using System.Linq;using AutoLot.Dal.Exceptions;using AutoLot.Dal.Repos;using AutoLot.Dal.Tests.Base;using AutoLot.Models.Entities;using Microsoft.EntityFrameworkCore;using Microsoft.EntityFrameworkCore.ChangeTracking;using Microsoft.EntityFrameworkCore.Query;using Microsoft.EntityFrameworkCore.Storage;using Xunit;