Testujte vašu architektúru pomocou NetArchTest
Máte definovaný na projekte typ architektúry? Onion / Clean / Vertical Slice / ... architektúru?
Prípadne máte vlastné architektonické pravidlá?
Ako si overujete že sú dodržiavané?
Máme .editorconfig, Roslynator, SonarCloud, ... Ale na architektúru toto nestačí.
Riešením môže byť použitie knižnice NetArchTest.
Táto knižnica umožňuje definovať rôzne pravidlá pre architektúru a následne ich priebežne overovať pomocou unit testov.
O aké pravidlá sa jedná? Najlepšie na príkladoch:
- doménova vrstva nesmie obsahovať závislosti na iných vrstvách
- prístup k databáze môže byť iba v infraštruktúrnej vrstve
- value objekty musia byť immutable
- repositáre musia mať sufix
Repository - DTO triedy nesmú byť použité v doménovej a infraštruktúrnej vrstve
asyncmetódy nesmú mať návratový typvoida suffixAsync- a mnoho ďalších pravidiel ktoré na vašom projekte môžu byť dôležité
Ako na to?
- Pridáme referenciu na knižnicu
NetArchTestdo testovacieho projektu.
dotnet add package NetArchTest.Rules
- Vytvoríme unit testy, ktoré budú overovať naše pravidlá.
[Fact]
public void RepositoriesShouldBeLocatedInInfrastructureNamespace()
{
var result = Types.InAssembly(typeof(ProductRepository).Assembly)
.That()
.ImplementInterface(typeof(IRepository)) // 👈 rule for repositories
.Should()
.ResideInNamespaceEndingWith("Infrastructure") // 👈 use rule
.GetResult();
result.IsSuccessful.Should().BeTrue();
}
[Fact]
public void DomainShouldNotReferenceInfrastructure()
{
var result = Types.InAssembly(typeof(ProductDto).Assembly)
.That()
.ResideInNamespace("EShop.Domains")
.ShouldNot()
.HaveDependencyOn("EShop.Infrastructure")
.GetResult();
result.IsSuccessful.Should().BeTrue();
}
- Môžeme si vytvoriť aj vlastné pravidlá.
public class IsRecordRule : ICustomRule
{
// 👇 use custom rule for checking if type is Record
public bool MeetsRule(TypeDefinition type)
=> type.GetMethods().Any(m => m.Name == "<Clone>$");
}
public static class CustomRules
{
// 👇 extension method to simplify the use of a custom rule
public static ConditionList BeRecord(this Conditions conditions)
=> conditions.MeetCustomRule(new IsRecordRule());
}
[Fact]
public void DtoShouldBeRecordType()
{
var result = Types.InAssembly(typeof(ProductDto).Assembly)
.That()
.HaveNameEndingWith("Dto")
.Should()
.BeRecord()
.GetResult();
result.IsSuccessful.Should().BeTrue();
}