如何编写参数化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
相关产品推荐
相关产品推荐

