Литмир - Электронная Библиотека
A
A

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
. Сделайте класс открытым и запечатанным, а также добавьте показанные далее операторы
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]
:

[Collection("Integration Tests")]

Унаследуйте все четыре класса от

BaseTest
, реализуйте интерфейс
IClassFixture
и приведите операторы
using
к показанному далее виду:

// CarTests.cs

using 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;

455
{"b":"847442","o":1}