I have test
@ArchTest
public static final ArchRule daoShouldBeUsedOnlyByHelper = theClass(SegmentDAO.class).should()
.onlyBeAccessed()
.byClassesThat(simpleName(SegmentHelper.class.getSimpleName())).orShould()
.onlyBeAccessed().byClassesThat(simpleName(SegmentHelperFake.class.getSimpleName()));
and the test fails like:
java.lang.AssertionError: Architecture Violation [Priority: MEDIUM] - Rule 'classes that have fully qualified name 'me.test.common.db.SegmentDAO' should only be accessed by classes that have fully qualified name 'me.test.common.helpers.db.SegmentHelper' or should only be accessed by classes that have fully qualified name 'me.test.common.test.SegmentHelperFake'' was violated (1 times):
Method <me.test.common.helpers.db.SegmentHelper.delete(int, int)> calls method <me.test.common.db.SegmentDAO.delete(int, int)> in (SegmentHelper.java:45) and Method <me.test.common.helpers.db.SegmentHelper.duplicate(int, int)> calls method <me.test.common.db.SegmentDAO.get(int, int)> in (SegmentHelper.java:51) and Method <me.test.common.helpers.db.SegmentHelper.get(int)> calls method <me.test.common.db.SegmentDAO.get(int)> in (SegmentHelper.java:29) and Method <me.test.common.helpers.db.SegmentHelper.get(int, int)> calls method <me.test.common.db.SegmentDAO.get(int, int)> in (SegmentHelper.java:38) and Method <me.test.common.helpers.db.SegmentHelper.insert(int, java.lang.String, java.sql.Timestamp, java.sql.Timestamp, int, int, java.lang.String)> calls method <me.test.common.db.SegmentDAO.insert(int, java.lang.String, java.sql.Timestamp, java.sql.Timestamp, int, int, java.lang.String)> in (SegmentHelper.java:23) and Method <me.test.common.helpers.db.SegmentHelper.removePartByTrackerId(int, int)> calls method <me.test.common.db.SegmentDAO.removePartByTracker(int, int)> in (SegmentHelper.java:72) and Method <me.test.common.helpers.db.SegmentHelper.updateFilters(int, int, java.lang.String)> calls method <me.test.common.db.SegmentDAO.get(int, int)> in (SegmentHelper.java:78) and Method <me.test.common.helpers.db.SegmentHelper.updateFilters(int, int, java.lang.String)> calls method <me.test.common.db.SegmentDAO.updateFilters(int, int, java.lang.String)> in (SegmentHelper.java:84) and Method <me.test.common.helpers.db.SegmentHelper.updateName(int, int, java.lang.String)> calls method <me.test.common.db.SegmentDAO.get(int, int)> in (SegmentHelper.java:61) and Method <me.test.common.helpers.db.SegmentHelper.updateName(int, int, java.lang.String)> calls method <me.test.common.db.SegmentDAO.updateName(int, int, java.lang.String)> in (SegmentHelper.java:67) and Method <me.test.common.test.SegmentHelperFake.delete(int, int)> calls method <me.test.common.db.SegmentDAO.delete(int, int)> in (SegmentHelperFake.java:49) and Method <me.test.common.test.SegmentHelperFake.duplicate(int, int)> calls method <me.test.common.db.SegmentDAO.get(int, int)> in (SegmentHelperFake.java:56) and Method <me.test.common.test.SegmentHelperFake.get(int)> calls method <me.test.common.db.SegmentDAO.get(int)> in (SegmentHelperFake.java:31) and Method <me.test.common.test.SegmentHelperFake.get(int, int)> calls method <me.test.common.db.SegmentDAO.get(int, int)> in (SegmentHelperFake.java:41) and Method <me.test.common.test.SegmentHelperFake.insert(int, java.lang.String, java.sql.Timestamp, java.sql.Timestamp, int, int, java.lang.String)> calls method <me.test.common.db.SegmentDAO.insert(int, java.lang.String, java.sql.Timestamp, java.sql.Timestamp, int, int, java.lang.String)> in (SegmentHelperFake.java:24) and Method <me.test.common.test.SegmentHelperFake.updateFilters(int, int, java.lang.String)> calls method <me.test.common.db.SegmentDAO.get(int, int)> in (SegmentHelperFake.java:79) and Method <me.test.common.test.SegmentHelperFake.updateFilters(int, int, java.lang.String)> calls method <me.test.common.db.SegmentDAO.updateFilters(int, int, java.lang.String)> in (SegmentHelperFake.java:85) and Method <me.test.common.test.SegmentHelperFake.updateName(int, int, java.lang.String)> calls method <me.test.common.db.SegmentDAO.get(int, int)> in (SegmentHelperFake.java:67) and Method <me.test.common.test.SegmentHelperFake.updateName(int, int, java.lang.String)> calls method <me.test.common.db.SegmentDAO.updateName(int, int, java.lang.String)> in (SegmentHelperFake.java:73)
But in mentions method calls that should be able to call it. Not sure what is w rong
A rule (in pseudo code)
// ...
.should().a()
.orShould().b();
will only pass when a
or b
applies.
In your case, neither condition a
("only be accessed by SegmentHelper
") nor b
("only be accessed by SegmentHelperFake
") applies on their own (as you seem to have accesses by both SegmentHelper
and SegmentHelperFake
).
You probably want to define another condition that already combines the options:
@ArchTest
ArchRule daoShouldBeUsedOnlyByHelper = theClass(SegmentDAO.class)
.should().onlyBeAccessed().byClassesThat(are(
equivalentTo(SegmentHelper.class)
.or(equivalentTo(SegmentHelperFake.class))
));
using
import static com.tngtech.archunit.core.domain.JavaClass.Predicates.equivalentTo;
import static com.tngtech.archunit.lang.conditions.ArchPredicates.are;