在ArchUnit中能否将方法定义转换为谓词?
问题
我想要编写测试用例,禁止系统内所有类调用外部定义的静态方法(本文中为com.vaadin.flow.internal.StringUtil类的方法)。目前我已通过以下代码实现该需求:
ArchRuleDefinition.noClasses().should().callMethodWhere( JavaAccess.Predicates.targetOwner(JavaClass.Predicates .assignableTo("com.vaadin.flow.internal.StringUtil"))) .check(new ClassFileImporter() .importPackages("com.example.application"));
不过ArchUnit已提供更简洁的定义方式:
ArchRuleDefinition.methods().that() .areDeclaredIn("com.vaadin.flow.internal.StringUtil")
若能将上述定义转换为谓词传入callMethodWhere,比如编写如下形式的代码,可让测试用例更易理解:
ArchRuleDefinition.noClasses().should() .callMethodWhere(transformInPredicate(ArchRuleDefinition.methods().that() .areDeclaredIn("com.vaadin.flow.internal.StringUtil"))) .check(new ClassFileImporter() .importPackages("com.example.application"));
请问这种转换是否可行?
回答
这种转换完全可行,借助ArchUnit内置的API就能实现,既保留简洁的语义表达,又能提升测试代码的可读性。
具体实现代码
你可以通过asPredicate()将方法规则转换为DescribedPredicate<JavaMethod>,再用JavaAccess.Predicates.target()把它适配为callMethodWhere所需的方法调用判断谓词:
ArchRuleDefinition.noClasses().should() .callMethodWhere(JavaAccess.Predicates.target( ArchRuleDefinition.methods().that() .areDeclaredIn("com.vaadin.flow.internal.StringUtil") .asPredicate() )) .check(new ClassFileImporter() .importPackages("com.example.application"));
关键逻辑说明
asPredicate():将MethodsShouldConjunction类型的方法规则直接转换为判断JavaMethod实例的谓词JavaAccess.Predicates.target():把方法谓词包装成适配方法调用(JavaMethodAccess)的谓词,完美匹配callMethodWhere的参数要求- 这种写法既利用了ArchRuleDefinition的简洁语法,又保持了原测试逻辑的正确性
内容的提问来源于stack exchange,提问作者brunovianarezende
相关产品推荐
相关产品推荐

