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.
Whenever the predefined fluent API (classes().that().….should().…
) does not offer a solution, you can define custom DescribedPredicate
s and ArchConditions
s 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
)));
}