You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写参数化ArchUnit测试?多方法名测试遇阻求助

批量测试指定方法名的ArchUnit解决方案

方案一:JUnit 5参数化测试配合ArchUnit

这是最直观的方案,每个方法名对应独立测试用例,互不影响:

import com.tngtech.archunit.core.domain.JavaMethod;
import com.tngtech.archunit.core.domain.JavaModifier;
import com.tngtech.archunit.core.importer.ImportOption;
import com.tngtech.archunit.junit.AnalyzeClasses;
import com.tngtech.archunit.lang.ArchCondition;
import com.tngtech.archunit.lang.ConditionEvents;
import com.tngtech.archunit.lang.SimpleConditionEvent;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.methods;

@AnalyzeClasses(packages = "your.target.package", importOptions = ImportOption.DoNotIncludeTests.class)
class MethodArchTests {

    @ParameterizedTest
    @ValueSource(strings = {"methodA", "methodB", "methodC"})
    void testSpecificMethod(String methodName) {
        ArchRule rule = methods()
                .that().haveName(methodName)
                .should(new ArchCondition<JavaMethod>("meet custom requirements") {
                    @Override
                    public void check(JavaMethod javaMethod, ConditionEvents events) {
                        // 这里编写你的自定义检查逻辑
                        // 示例:检查方法是否为public
                        if (!javaMethod.getModifiers().contains(JavaModifier.PUBLIC)) {
                            events.add(SimpleConditionEvent.violated(javaMethod, 
                                String.format("方法 %s 不是public修饰", methodName)));
                        }
                    }
                });

        rule.check(classesToTest);
    }
}

需要确保项目引入了JUnit 5参数化依赖(junit-jupiter-params),每个方法名会单独执行测试,某一个用例失败不会影响其他用例的运行。

方案二:合并为单一规则批量检查

如果不想用参数化测试,可以把所有目标方法的检查合并到一个规则中,这样能一次性收集所有违规,不会因单个违规终止测试:

import com.tngtech.archunit.core.domain.JavaMethod;
import com.tngtech.archunit.lang.ArchCondition;
import com.tngtech.archunit.lang.ConditionEvents;
import com.tngtech.archunit.lang.SimpleConditionEvent;
import org.junit.jupiter.api.Test;

import java.util.Arrays;
import java.util.List;

import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.methods;

class MethodArchTests {

    @Test
    void testAllTargetMethods() {
        List<String> targetMethodNames = Arrays.asList("methodA", "methodB", "methodC");
        // 用正则匹配所有目标方法名
        String methodNamePattern = String.join("|", targetMethodNames);

        ArchRule rule = methods()
                .that().haveNameMatching(methodNamePattern)
                .should(new ArchCondition<JavaMethod>("meet custom requirements") {
                    @Override
                    public void check(JavaMethod javaMethod, ConditionEvents events) {
                        String currentMethodName = javaMethod.getName();
                        // 针对当前方法执行自定义检查
                        // 示例:检查方法是否包含特定注解
                        if (!javaMethod.isAnnotatedWith(YourCustomAnnotation.class)) {
                            events.add(SimpleConditionEvent.violated(javaMethod,
                                String.format("方法 %s 缺少 @YourCustomAnnotation 注解", currentMethodName)));
                        }
                    }
                });

        rule.check(classesToTest);
    }
}

这种方式的核心是用haveNameMatching配合正则表达式匹配所有目标方法,然后在同一个ArchCondition中处理所有检查,所有违规会被统一收集,测试结束后一次性报告。

核心注意事项

  • 自定义ArchCondition时,禁止直接抛出异常,必须通过ConditionEvents.add()添加违规事件,否则ArchUnit会在遇到第一个违规时直接终止测试。
  • 使用参数化测试时,要确保测试类上的@AnalyzeClasses配置正确,或者手动导入需要测试的类集合。

内容的提问来源于stack exchange,提问作者Oleg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 06:30:20