【问题标题】:ArchUnit: how to test for imports of specific classes outside of current package?ArchUnit:如何测试当前包之外特定类的导入?
【发布时间】:2020-12-18 16:36:47
【问题描述】:

为了外部化 UI 字符串,我们使用支持的“消息类”方法,例如在 Eclipse 和其他 IDE 中。这种方法要求在每个需要一些 UI 字符串的包中,必须有一个“消息”类,它提供一个静态方法String getString(key),通过该方法可以获取实际的字符串以显示给用户。使用 Java 的 i18n 资源机制在内部访问/获取字符串。

特别是。经过一些重构 - 我们一次又一次地从一个类 Messages 中意外导入来自不同的包

因此,我想创建一个 archunit 规则,检查我们是否只从非常 same 包中访问名为“Messages”的类。 IE。如果包 x.y.z 与当前类(即包含导入的类)不是同一个包,则类 x.y.z.Messages 的每次导入都是错误

我已经做到了:

@ArchTest
void preventReferencesToMessagesOutsideCurrentPackage(JavaClasses classes) {
    ArchRule rule;
    rule = ArchRuleDefinition.noClasses()
        .should().accessClassesThat().haveNameMatching("Messages")
        .???
        ;
    rule.check(classes);
}

但现在我被困在了???。 一个条件“并且引用/导入的类“消息”与 this 类不在同一个包中”怎么能表达出来?

我不知何故迷失了所有这些 Archunit 方法,这些方法似乎都不适合这里,也不适合构成上述条件。可能我只是看不到很多树的森林。 有什么建议或指导吗?

【问题讨论】:

    标签: archunit


    【解决方案1】:

    您需要对JavaAccess 的实例进行操作以验证依赖关系。 JavaAccess 提供有关调用者和目标的信息,以便您可以根据两个类的包名称动态验证访问。

    DescribedPredicate<JavaAccess<?>> isForeignMessageClassPredicate = 
            new DescribedPredicate<JavaAccess<?>>("target is a foreign message class") {
    
        @Override
        public boolean apply(JavaAccess<?> access) {
            JavaClass targetClass = access.getTarget().getOwner();
            if ("Message".equals(targetClass.getSimpleName())) {
                JavaClass callerClass = access.getOwner().getOwner();
                return !targetClass.getPackageName().equals(callerClass.getPackageName());
            }
    
            return false;
        }
    };
    
    ArchRule rule =
        noClasses().should().accessTargetWhere(isForeignMessageClassPredicate);
    

    【讨论】:

    • 哇 - 一个泛就绪的解决方案!工作完美。它向我展示了一种进行某些检查的新方法——我想我将能够使用该模式进行进一步的检查。非常感谢!我欠你的!
    猜你喜欢
    • 2022-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-11
    • 2010-09-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多