Search code examples
javaarchunit

How to check with ArchUnit that all DTO classes should have default constructor


How to check with ArchUnit that all .*DTO classes should have default constructor.

classes().that()
         .haveNameMatching(".*DTO")
         .should()
         .haveOnlyPrivateConstructors();// instead of this something like 'haveDefaultConstructor'

is there a way in check haveDefaultConstructor()? I was not able to find it in docs

I think this is very common case when you want to test for default constructors.


Solution

  • If you really want to find (compiler-generated) default constructors, you need to be aware of two things:

    1. ArchUnit probably cannot distinguish the bytecode of a compiler-generated default constructor from a user-generated empty constructor (cf. ArchUnit#322).
    2. Unless you limit your rule to outer classes, finding default constructors is tricky, cf. ArchUnit#349.

    But from a practical perspective, you probably rather want to ensure that your DTOs have a public constructor without parameters? Then you could use

    classes()
        .that().haveSimpleNameEndingWith("DTO")
        .should(new ArchCondition<JavaClass>("have a public constructor without parameters") {
            @Override
            public void check(JavaClass javaClass, ConditionEvents events) {
                boolean satisfied = javaClass.getConstructors().stream()
                    .anyMatch(constructor ->
                        constructor.getModifiers().contains(JavaModifier.PUBLIC) 
                                && constructor.getParameters().isEmpty()
                    );
                String message = javaClass.getDescription() + (satisfied ? " has" : " does not have")
                        + " a public constructor without parameters";
                events.add(new SimpleConditionEvent(javaClass, satisfied, message));
            }
        });
    

    If you want to ensure that your DTOs only have a public constructor without parameters, you could replace anyMatch by allMatch in the above solution.