java - 如何创建 ArchUnit 规则来验证引发的所有异常是否继承自特定的自定义异常?

标签 java unit-testing archunit

我的架构规则之一是应用程序代码抛出的所有异常都必须是 CustomException 或 CustomException 的子类。

我在 ArchUnit 中编写此规则时遇到困难。我目前拥有的内容如下:

private static final ArchCondition<JavaClass> THROWS_NON_CUSTOM_EXCEPTION = callCodeUnitWhere( 
   target(is(constructor()))
      .and(
         originOwner(
            is(assignableTo(Throwable.class)) 
            .and(not(assignableTo(CustomException.class)))
         )
      )
   );

@ArchTest public static final ArchRule noNonCustomExceptions = noClasses()
   .should(THROWS_NON_CUSTOM_EXCEPTION);

运行此规则会返回 true(JUnit 测试通过),即使我的代码抛出的异常不是 CustomException。

我已经测试了规则的一部分,该部分检测构造函数具有可分配给 Throwable 的所有者:

private static final ArchCondition<JavaClass> THROWS_NON_CUSTOM_EXCEPTION =    
   callCodeUnitWhere( 
      target(is(constructor()))
         .and(
            originOwner( 
               is(assignableTo(Throwable.class))
            )
         )
   );

这会正确返回代码中创建任何 Throwable 的每个位置。

问题似乎出在我的代码中,该代码尝试查找不可分配给 CustomException 的所有者:

   private static final ArchCondition<JavaClass> THROWS_NON_CUSTOM_EXCEPTION = callCodeUnitWhere( 
      target(is(constructor()))
         .and(
            originOwner( 
               is(not(assignableTo(CustomException.class)))
            )
         )
   );

这将返回每个构造函数,甚至是那些可分配给 CustomException 的异常构造函数。

在 ArchUnit 中编写一条规则以返回调用其所有者可分配给 Throwable 而不能分配给 CustomException 的构造函数的每个代码单元的正确方法是什么?

最佳答案

我认为你只需要将已有的部分组合起来即可。以下代码对我有用:

noClasses().should().callCodeUnitWhere(
    JavaCall.Predicates.target(
        AccessTarget.Predicates.constructor()
        .and(AccessTarget.Predicates.declaredIn(JavaClass.Predicates.assignableTo(Throwable.class)))
        .and(DescribedPredicate.not(AccessTarget.Predicates.declaredIn(JavaClass.Predicates.assignableTo(BaseException.class))))
    )
);

如果您的 BaseException 位于分析范围内,您将需要排除该类:noClasses().that(not(belongToAnyOf(BaseException.class)))

关于java - 如何创建 ArchUnit 规则来验证引发的所有异常是否继承自特定的自定义异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63506602/

相关文章:

java - 在 Blackberry 中实现 ArrayList

java - createDatastore 是否具有破坏性?

c++ - 在手动定义的套件树中 boost 测试用例和套件装置

unit-testing - Golang Mocking - 类型冲突问题

java - Archunit 匹配泛型类型的构造函数

java - 如果在 JFrame 代码中调用 repaint(),JPanel 不会重绘

java - 让 Spring @Value 注释与 Grails 一起使用

Java Elasticsearch 数据库测试

java - 如何使用 archunit 验证方法注释是否使用具有特定值的属性

java - ArchUnit - 确保方法参数被注释