我如何创建一个 ArchUnit 规则来验证所有抛出的异常都继承自特定的自定义异常?
How do I create an ArchUnit rule to verify all exceptions thrown inherit from a specific custom exception?
我的架构规则之一是应用程序代码抛出的所有异常都必须是 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);
运行 这条规则 returns 正确(JUnit 测试通过),即使我的代码抛出的异常也不是 CustomException。
我已经测试了检测构造函数具有可分配给 Throwable 的所有者的规则部分:
private static final ArchCondition<JavaClass> THROWS_NON_CUSTOM_EXCEPTION =
callCodeUnitWhere(
target(is(constructor()))
.and(
originOwner(
is(assignableTo(Throwable.class))
)
)
);
这正确 returns 代码中创建任何 Throwable 的每个地方。
问题似乎出在我的代码中,它试图找到不能分配给 CustomException 的所有者:
private static final ArchCondition<JavaClass> THROWS_NON_CUSTOM_EXCEPTION = callCodeUnitWhere(
target(is(constructor()))
.and(
originOwner(
is(not(assignableTo(CustomException.class)))
)
)
);
这 returns 每个构造函数,甚至是那些可分配给 CustomException 的异常。
在 ArchUnit 中编写规则的正确方法是什么 returns 每个调用其所有者可分配给 Throwable 的构造函数的代码单元,并且 不可 可分配给自定义异常?
我认为您只需要组合已有的部分即可。以下代码对我有用:
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
位于分析范围内,您将需要排除 class:noClasses().that(not(belongToAnyOf(BaseException.class)))
。
我的架构规则之一是应用程序代码抛出的所有异常都必须是 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);
运行 这条规则 returns 正确(JUnit 测试通过),即使我的代码抛出的异常也不是 CustomException。
我已经测试了检测构造函数具有可分配给 Throwable 的所有者的规则部分:
private static final ArchCondition<JavaClass> THROWS_NON_CUSTOM_EXCEPTION =
callCodeUnitWhere(
target(is(constructor()))
.and(
originOwner(
is(assignableTo(Throwable.class))
)
)
);
这正确 returns 代码中创建任何 Throwable 的每个地方。
问题似乎出在我的代码中,它试图找到不能分配给 CustomException 的所有者:
private static final ArchCondition<JavaClass> THROWS_NON_CUSTOM_EXCEPTION = callCodeUnitWhere(
target(is(constructor()))
.and(
originOwner(
is(not(assignableTo(CustomException.class)))
)
)
);
这 returns 每个构造函数,甚至是那些可分配给 CustomException 的异常。
在 ArchUnit 中编写规则的正确方法是什么 returns 每个调用其所有者可分配给 Throwable 的构造函数的代码单元,并且 不可 可分配给自定义异常?
我认为您只需要组合已有的部分即可。以下代码对我有用:
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
位于分析范围内,您将需要排除 class:noClasses().that(not(belongToAnyOf(BaseException.class)))
。