ArchUnit es una biblioteca gratuita, simple y extensible para verificar la arquitectura de su código Java utilizando cualquier framework de testing. Es decir, ArchUnit puede verificar dependencias entre paquetes y clases, capas y segmentos, verificar dependencias cíclicas y más. Lo hace analizando el código de bytes Java, importando todas las clases en una estructura de código Java.
Veamos un ejemplo, queremos poner unas reglas a nuestras interfaces :
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses;
@AnalyzeClasses(locations = InterfaceRulesTest.RelevantExampleClasses.class)
public class InterfaceRulesTest {
@ArchTest
static final ArchRule interfaces_should_not_have_names_ending_with_the_word_interface =
noClasses().that().areInterfaces().should().haveNameMatching(".*Interface");
@ArchTest
static final ArchRule interfaces_should_not_have_simple_class_names_containing_the_word_interface =
noClasses().that().areInterfaces().should().haveSimpleNameContaining("Interface");
@ArchTest
static final ArchRule interfaces_must_not_be_placed_in_implementation_packages =
noClasses().that().resideInAPackage("..impl..").should().beInterfaces();
public static class RelevantExampleClasses implements LocationProvider {
@Override
public Set<Location> get(Class<?> testClass) {
Set<Location> result = new HashSet<>();
result.addAll(Locations.ofClass(SomeBusinessInterface.class));
result.addAll(Locations.ofClass(SomeDao.class));
result.addAll(Locations.ofClass(SomeInterfacePlacedInTheWrongPackage.class));
return result;
}
}
}
También podríamos analizar que ningún servicio retorne un objeto del modelo o que estén bien definidas las dependencias o/y los nombres de las clases, etc.
Veamos otro ejemplo :
@AnalyzeClasses(packages = "com.tngtech.archunit.example.layers")
public class DaoRulesTest {
@ArchTest
static final ArchRule DAOs_must_reside_in_a_dao_package =
classes().that().haveNameMatching(".*Dao").should().resideInAPackage("..dao..")
.as("DAOs should reside in a package '..dao..'");
@ArchTest
static final ArchRule entities_must_reside_in_a_domain_package =
classes().that().areAnnotatedWith(Entity.class).should().resideInAPackage("..domain..")
.as("Entities should reside in a package '..domain..'");
@ArchTest
static final ArchRule only_DAOs_may_use_the_EntityManager =
noClasses().that().resideOutsideOfPackage("..dao..")
.should().accessClassesThat().areAssignableTo(EntityManager.class)
.as("Only DAOs may use the " + EntityManager.class.getSimpleName());
@ArchTest
static final ArchRule DAOs_must_not_throw_SQLException =
noMethods().that().areDeclaredInClassesThat().haveNameMatching(".*Dao")
.should().declareThrowableOfType(SQLException.class);
}
Y se pueden hacer muchas cosas más, es muy simple de usar. Agregamos la dependencia :
dependencies {
testImplementation 'com.tngtech.archunit:archunit:0.23.1'
}
o con maven :
<dependency>
<groupId>com.tngtech.archunit</groupId>
<artifactId>archunit</artifactId>
<version>0.23.1</version>
<scope>test</scope>
</dependency>
Y a codear test!!!
También existe para .net (pero eso es tema para otro post)
Dejo link : https://www.archunit.org/