TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.75K subscribers
Post #3117 2.14K
День 2595. #ЗаметкиНаПолях
5 Архитектурных Тестов Необходимых Каждому .NET-Проекту. Начало

Каждый проект начинается с благих намерений. Вы согласовываете границы слоёв, соглашения об именовании, направление зависимостей. Через полгода кто-то переносит доменный сервис в проект инфраструктуры, обработчик получает имя не по соглашению или внутренний класс становится публичным, потому что это значение по умолчанию. Архитектурные тесты предотвращают это. Они превращают архитектурные правила в автоматизированные тесты, которые запускаются в CI. Вот архитектурные тесты, которые пригодятся каждому проекту.

ArchUnitNET - позволяет писать архитектурные правила, используя fluent API, и запускать их как обычные тесты. Для примера будем использовать xUnit, хотя поддерживаются и другие фреймворки:
dotnet add package TngTech.ArchUnitNET.xUnit

Нужен базовый класс, который загружает все сборки, которые мы хотим протестировать. Каждый слой получает «тип привязки» для получения ссылки на сборку во время компиляции:
public abstract class BaseTest
{
protected static readonly Assembly
DomainAssembly = typeof(User).Assembly;
protected static readonly Assembly
ApplicationAssembly = typeof(ICommand).Assembly;
// … аналогично остальные сборки

protected static readonly Architecture
Architecture = new ArchLoader()
.LoadAssemblies(
DomainAssembly,
ApplicationAssembly,
…)
.Build();
}

ArchLoader сканирует сборки и создает в памяти модель всех типов и их зависимостей.
Каждый тестовый класс наследует от BaseTest.

1. Тесты зависимостей слоёв
Внутренние слои в чистой архитектуре не должны ссылаться на внешние. В большинстве конфигураций чистой архитектуры ссылки на проекты уже предотвращают очевидные нарушения. Вы не можете добавить ссылку из приложения в инфраструктуру, т.к. инфраструктура уже ссылается на приложение, и компилятор не допустит циклических зависимостей.
Но тесты всё равно нужны, т.к. ссылки на проекты — не единственный способ проникновения зависимостей. NuGet, используемый в инфраструктуре, может содержать типы, которые проникают в приложение через транзитивные ссылки. Кто-то может реорганизовать решение и изменить граф ссылок проекта. Тесты — страховочная сетка и в то же время документальное подтверждение задуманной архитектуры.
public class LayerTests : BaseTest
{
private static readonly
IObjectProvider<IType> DomainLayer =
Types()
.That()
.ResideInAssembly(DomainAssembly)
.As("Domain layer");

private static readonly
IObjectProvider<IType> ApplicationLayer =
Types()
.That()
.ResideInAssembly(ApplicationAssembly)
.As("Application layer");

//…

[Fact]
public void Domain_ShouldNotDependOn_Application ()
{
Types().That().Are(DomainLayer).Should()
.NotDependOnAny(ApplicationLayer)
.Check(Architecture);
}

// … аналогично тесты остальных слоёв
}

Добавьте тесты для всех неверных направлений зависимостей.

Fluent API читается как английский язык: «Типы, находящиеся в доменном слое, не должны зависеть от каких-либо типов в прикладном слое». При возникновении нарушения тест точно указывает, какой тип от какого зависит.

Вы также можете расширить его. Например, добавить тесты, что определённые пространства имен внутри слоя не могут ссылаться друг на друга (например, Application.Orders не должны зависеть от Application.Users). Это может быть отлично для обеспечения вертикальной архитектуры, где каждая функция самодостаточна, или внутри модульного монолита, где модули не должны зависеть друг от друга.

Продолжение следует…

Источник:
https://www.milanjovanovic.tech/blog/5-architecture-tests-you-should-add-to-your-dotnet-projects
  • 👍 17
More from @netdeveloperdiary
  1. Sep 27, 2026День 2797. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Окончание Начало Продол…
  2. Sep 26, 2026День 2796. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Продолжение Начало Три…
  3. Sep 25, 2026День 2795. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Начало Проблема с позиц…
  4. Sep 24, 2026День 2794. #Оффтоп #Здоровье Сегодня будет необычный пост. Завтра в Москве стартует конфер…
  5. Sep 23, 2026День 2793. #ЗаметкиНаПолях #SQL 10 Редких Возможностей SQL, Которые Стоит Знать Каждому. Ч…
  6. Sep 22, 2026День 2792. #ЗаметкиНаПолях #SQL 10 Редких Возможностей SQL, Которые Стоит Знать Каждому. Ч…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →