Reputation: 26084
I'm using ArchUnit and I want to check if all classes residing in a package declare one only public method called execute
. I have this code:
JavaClasses importedClasses = new ClassFileImporter().importPackages("my.package");
methods().that().arePublic().should().haveName("execute").check(importedClasses);
It works but I would like this test to fail when execute
method is absent in any class. With my code, test passes because all public methods (zero) actually have name "execute".
Upvotes: 2
Views: 1521
Reputation: 3142
In order to test classes, you have to base your ArchRule
on them (not on the methods that might not exist). You can use a custom condition to count public methods and test their names, e.g. like this:
ArchRule rule = classes()
.that().resideInAPackage("my.package")
.should(new ArchCondition<JavaClass>("have exactly one public method named 'execute'") {
@Override
public void check(JavaClass javaClass, ConditionEvents events) {
List<JavaMethod> publicMethods = javaClass.getMethods().stream()
.filter(javaMethod -> javaMethod.getModifiers().contains(PUBLIC))
.collect(toList());
boolean satisfied = false;
String message = javaClass.getName() + " contains " + publicMethods.size() + " public method";
if (publicMethods.size() == 1) {
JavaMethod method = publicMethods.get(0);
satisfied = method.getName().equals("execute");
message += " named '" + method.getName() + "' " + method.getSourceCodeLocation();
} else {
message += "s " + javaClass.getSourceCodeLocation();
}
events.add(new SimpleConditionEvent(javaClass, satisfied, message));
}
});
Upvotes: 2