测试@Service 的ArchUnit 规则仅依赖于自己包中的@Repository?
ArchUnit rule to test @Service only depends on @Repository in own package?
我想编写一个 ArchUnit 规则来验证服务 class(由 @Service
Spring 注释注释)将仅使用其自己包中的存储库,不是来自其他包。
我目前有:
noClasses().that()
.areAnnotatedWith(Service.class)
.should()
.dependOnClassesThat().areAnnotatedWith(Repository.class)
.orShould().dependOnClassesThat().haveSimpleNameEndingWith("Repository")
这不好,因为它根本不允许对存储库有任何依赖。
或者,我可以这样做:
noClasses().that()
.resideInAPackage("com.company.backend.user")
.and()
.areAnnotatedWith(Service.class)
.should()
.dependOnClassesThat(resideOutsideOfPackage("com.company.backend.user").and(annotatedWith(Repository.class)))
.orShould().dependOnClassesThat(have(resideOutsideOfPackage("com.company.backend.user").and(simpleNameEndingWith("Repository"))))
.as("Service classes should only use Repository class(es) from the own package");
但是我重复包名称 com.company.backend.user
3 次 和 我需要为每个包定义这个规则。
您需要定义依赖项的谓词并对其进行操作。
classes()
.that()
.areAnnotatedWith(Service.class)
.should(ArchConditions.onlyHaveDependenciesWhere(RepositoryAccessesAreOnlyWithinPackage.PREDICATE));
谓词检查访问目标是否为存储库,如果是,它将验证目标是否位于与调用相同的包中 class:
private static class RepositoryAccessesAreOnlyWithinPackage
extends DescribedPredicate<Dependency> {
public static final DescribedPredicate<Dependency> PREDICATE = new RepositoryAccessesAreOnlyWithinPackage();
public RepositoryAccessesAreOnlyWithinPackage() {
super("repository accesses are only within the same package");
}
@Override
public boolean apply(Dependency dependency) {
if (isRepositoryAccess(dependency)) {
return areClassesInTheSamePackage(dependency.getOriginClass(), dependency.getTargetClass());
}
return true;
}
private boolean isRepositoryAccess(Dependency dependency) {
return dependency.getTargetClass().isAnnotatedWith(Repository.class);
}
private boolean areClassesInTheSamePackage(JavaClass originClass, JavaClass targetClass) {
return originClass.getPackageName().equals(targetClass.getPackageName());
}
}
我想编写一个 ArchUnit 规则来验证服务 class(由 @Service
Spring 注释注释)将仅使用其自己包中的存储库,不是来自其他包。
我目前有:
noClasses().that()
.areAnnotatedWith(Service.class)
.should()
.dependOnClassesThat().areAnnotatedWith(Repository.class)
.orShould().dependOnClassesThat().haveSimpleNameEndingWith("Repository")
这不好,因为它根本不允许对存储库有任何依赖。
或者,我可以这样做:
noClasses().that()
.resideInAPackage("com.company.backend.user")
.and()
.areAnnotatedWith(Service.class)
.should()
.dependOnClassesThat(resideOutsideOfPackage("com.company.backend.user").and(annotatedWith(Repository.class)))
.orShould().dependOnClassesThat(have(resideOutsideOfPackage("com.company.backend.user").and(simpleNameEndingWith("Repository"))))
.as("Service classes should only use Repository class(es) from the own package");
但是我重复包名称 com.company.backend.user
3 次 和 我需要为每个包定义这个规则。
您需要定义依赖项的谓词并对其进行操作。
classes()
.that()
.areAnnotatedWith(Service.class)
.should(ArchConditions.onlyHaveDependenciesWhere(RepositoryAccessesAreOnlyWithinPackage.PREDICATE));
谓词检查访问目标是否为存储库,如果是,它将验证目标是否位于与调用相同的包中 class:
private static class RepositoryAccessesAreOnlyWithinPackage
extends DescribedPredicate<Dependency> {
public static final DescribedPredicate<Dependency> PREDICATE = new RepositoryAccessesAreOnlyWithinPackage();
public RepositoryAccessesAreOnlyWithinPackage() {
super("repository accesses are only within the same package");
}
@Override
public boolean apply(Dependency dependency) {
if (isRepositoryAccess(dependency)) {
return areClassesInTheSamePackage(dependency.getOriginClass(), dependency.getTargetClass());
}
return true;
}
private boolean isRepositoryAccess(Dependency dependency) {
return dependency.getTargetClass().isAnnotatedWith(Repository.class);
}
private boolean areClassesInTheSamePackage(JavaClass originClass, JavaClass targetClass) {
return originClass.getPackageName().equals(targetClass.getPackageName());
}
}