I would like to check whether FOO.model is only accessed by FOO.service and BAR.model is only accessed by BAR.service and so on.
Is there a way to achieve this with ArchUnit? Like (pseudocode)
classes() .that().resideInAPackage("{PLACEHOLDER}.model") .should().onlyBeAccessed().byAnyPackage("{PLACEHOLDER}.service");
I’m aware I could write a test that iterates over all FOO, BAR etc packages, or write a separate test for every package, but I’m looking for a generic out-of-the-box solution where I do not have to update my test class every time I introduce a new package.
Advertisement
Answer
You can use a custom condition to test the origin of each access:
classes() .that().resideInAPackage("..model") .should(new ArchCondition<JavaClass>("only be accessed from the corresponding service package") { @Override public void check(JavaClass javaClass, ConditionEvents conditionEvents) { javaClass.getAccessesToSelf().forEach(access -> { String originPackageName = access.getOrigin().getOwner().getPackageName(); String targetPackageName = access.getTarget().getOwner().getPackageName(); String expectedOriginPackageName = targetPackageName.replace(".model", ".service"); boolean satisfied = originPackageName.equals(expectedOriginPackageName); conditionEvents.add(new SimpleConditionEvent(access, satisfied, access.getDescription())); }); } });
(There are probably more sophisticated ways to construct expectedOriginPackageName
…)