TNG / ArchUnit

A Java architecture test library, to specify and assert architecture rules in plain Java
http://archunit.org
Apache License 2.0
3.17k stars 287 forks source link

Add method support for function callMethod #1228

Open rodrigobittencourtlima opened 7 months ago

rodrigobittencourtlima commented 7 months ago

Currently, it is possible to validate that certain classes must call a specific method from another class using the following rule:

@ArchTest
    public final ArchRule classShouldCallAudit = ArchRuleDefinition.classes().that()
            .areAnnotatedWith(Transactional.class).should()
            .callMethod(Audit.class, "audit", String.class, String.class)
            .as("Ensure system audit");

It would be interesting to add the same possibility to methods, using something similar to:

@ArchTest
    public final ArchRule methodShouldCallAudit = ArchRuleDefinition.methods().that()
            .areAnnotatedWith(Transactional.class).should()
            .callMethod(Audit.class, "audit", String.class, String.class)
            .as("Ensure system audit");
hankem commented 7 months ago

I agree that this would be a nice addition to the API!

For now, you can use the following workaround:

@ArchTest
public final ArchRule methodShouldCallAudit = ArchRuleDefinition.methods().that()
    .areAnnotatedWith(Transactional.class)
    .should(ArchCondition.from(DescribedPredicate.describe("call Audit.audit(String, String)", method ->
        method.getMethodCallsFromSelf().stream()
            .map(JavaMethodCall::getTarget)
            .anyMatch(methodCallTarget -> {
                List<JavaClass> rawParameterTypes = methodCallTarget.getRawParameterTypes();
                return methodCallTarget.getOwner().isEquivalentTo(Audit.class)
                    && methodCallTarget.getName().equals("audit")
                    && rawParameterTypes.size() == 2
                    && rawParameterTypes.get(0).isEquivalentTo(String.class)
                    && rawParameterTypes.get(1).isEquivalentTo(String.class);
            })
    )))
    .as("Ensure system audit");
rodrigobittencourtlima commented 7 months ago

Amazing @hankem! Thank you!