Search code examples
javaarchitecturearchunit

ArchUnit rule to negate package access?


I stumbled upon the following snippet.

ArchRule myRule = classes()
    .that().resideInAPackage("..core..")
    .should().onlyBeAccessed().byAnyPackage("..controller..");

I wonder how I can negate this condition so, the test should check if the core package is not accessed by the controller package?


Solution

  • You can use ClassesShould.accessClassesThat(), which (as its JavaDoc suggests) usually makes more sense the negated way:

    import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses;
    // ...
    
      noClasses()
          .that().resideInAPackage("..controller..")
          .should().accessClassesThat().resideInAPackage("..core..");
    

    You can also stick to classes() and use GivenClasses.should(…) or GivenClassesConjunction.should(…) with a flexible ArchCondition. For your case, it can be easily composed from pre-defined conditions and predicates:

    import static com.tngtech.archunit.core.domain.JavaClass.Predicates.resideInAPackage;
    import static com.tngtech.archunit.lang.conditions.ArchConditions.accessClassesThat;
    import static com.tngtech.archunit.lang.conditions.ArchConditions.not;
    import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes;
    // ...
    
        classes()
            .that().resideInAPackage("..controller..")
            .should(not(accessClassesThat(resideInAPackage("..core.."))));