Héctor
Héctor

Reputation: 26084

Is it possible to check if method is declared in a group of classes?

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

Answers (1)

Manfred
Manfred

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

Related Questions