0

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

1 Answer 1

1

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;

Not the answer you're looking for? Browse other questions tagged or ask your own question.