Translate

viernes, 22 de abril de 2022

Testea tu arquitectura java con ArchUnit


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/