archunit

Test annotated class only has one public method


What is the best way to write an ArchUnit test that tests that classes that are annotated with a specific annotation, e.g. the Spring Framework @Component annotation, only have one public method?

I haven't tried anything yet because I am still learning ArchUnit.


Solution

  • Whenever the predefined fluent API (classes().that().….should().…) does not offer a solution, you can define custom DescribedPredicates and ArchConditionss and use classes().that(…).should(…).

    For your issue, I would use this:

    import com.tngtech.archunit.junit.ArchTest;
    import com.tngtech.archunit.lang.ArchRule;
    
    import static com.tngtech.archunit.base.DescribedPredicate.describe;
    import static com.tngtech.archunit.core.domain.JavaModifier.PUBLIC;
    import static com.tngtech.archunit.core.domain.properties.HasModifiers.Predicates.modifier;
    import static com.tngtech.archunit.lang.conditions.ArchConditions.have;
    import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes;
    
    public class StackOverflow76272127 {
    
      @ArchTest
      ArchRule components_should_have_only_one_public_method =
          classes()
              .that().areAnnotatedWith(Component.class)
              .should(have(describe("only one public method", javaClass ->
                  javaClass.getMethods().stream().filter(modifier(PUBLIC)).count() == 1
              )));
    }