ArchUnit rule to negate package access?

Viewed 235

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?

1 Answers

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.."))));
Related