ArchUnit: как избежать нарушения зависимости от классов Java

Я хочу убедиться, что классы в данном пакете относятся только к классам, которые находятся в самом пакете. Однако я получаю нарушение, сообщая, что класс a зависит, например, от java.lang.String, что для меня совершенно нормально. Есть ли способ игнорировать базовые пакеты Java?

        @ArchTest
        static final ArchRule zeroDependencyOfDomain = noClasses().that()
            .resideInAPackage("..domain..")
            .should().dependOnClassesThat()
            .resideOutsideOfPackages("..domain..");

3 ответа

Если вы не хотите явно указывать все внешние пакеты, такие как java., javax., com.google., org.apache.и т. д., и вы просто заботитесь о пакетах проекта, тогда вы можете просто присоединиться к двум условиям, таким как «домен или внешняя библиотека».

      String PROJECT_PACKAGE = "com.myproject..";

DescribedPredicate<JavaClass> domainOrExternalLibPredicate = JavaClass.Predicates.resideInAnyPackage("..domain..")
    .or(JavaClass.Predicates.resideOutsideOfPackage(PROJECT_PACKAGE));

@ArchTest
static final ArchRule zeroDependencyOfDomain = classes().that()
    .resideInAPackage("..domain..")
    .should().onlyDependOnClassesThat()
    .resideInAnyPackage(domainOrExternalLibPredicate);

В этой касте внешняя библиотека определяется как все, что находится за пределами вашего PROJECT_PACKAGE.

Вы можете явно разрешить зависимости для пакетов Java:

@ArchTest
static final ArchRule zeroDependencyOfDomain = noClasses().that()
    .resideInAPackage("..domain..")
    .should().dependOnClassesThat()
    .resideOutsideOfPackages("..domain..", "java..");

Вы также можете использовать classes() а также onlyDependOnClassesThat(), который немного легче читать на мой взгляд:

@ArchTest
static final ArchRule zeroDependencyOfDomain = classes().that()
    .resideInAPackage("..domain..")
    .should().onlyDependOnClassesThat()
    .resideInAnyPackage("..domain..", "java..");

Подобно другому ответу, я также не нашел лучшего способа, чем этот:

private static final String[] COMMON_PACKAGES = {
    "java..",
    "javax..",
    "com.google..",
    "org.springframework.."};

@ArchTest
final ArchRule classesInProdutPackageNoOutsideAccess =
    classes()
        .that()
        .resideInAnyPackage(PACKAGE_FOO)
        .should()
        .onlyAccessClassesThat()
        .resideInAnyPackage(commonPackagesAnd(PACKAGE_FOO));


private static String[] commonPackagesAnd(String... packages) {
    return ArrayUtils.addAll(packages, COMMON_PACKAGES);
}
Другие вопросы по тегам