ArchUnit误将Kotlin合成类Phone$WhenMappings判定为违规问题求助
解决ArchUnit检测Kotlin合成类导致的报错问题
我写了一个ArchUnit测试用例,用来校验shared包下只能包含接口、枚举类和数据类。但遇到个问题:当Kotlin代码里用when表达式处理枚举时,编译器会自动生成Phone$WhenMappings这类合成类,ArchUnit会把它当成普通类进行分析,导致测试不符合规则而报错。
解决方案1:排除所有Kotlin合成类
Kotlin生成的合成类通常带有$符号后缀,可以直接通过名称匹配排除这类类:
Java示例
classes().that().resideInAPackage("shared..") .and().notHaveNameMatching(".*\\$.*") .should().beInterfaces() .orShould().beEnums() .orShould().beDataClasses();
Kotlin示例
classes() .that().resideInAPackage("shared..") .and().notHaveNameMatching(".*\\$.*") .should { clazz -> clazz.isInterface || clazz.isEnum || clazz.isDataClass }
解决方案2:精准识别并排除合成类
如果担心误排除正常的内部类,可以通过kotlin.Metadata注解的标志位来精准判断是否为Kotlin合成类:
Java示例
classes().that().resideInAPackage("shared..") .and().notSatisfy(clazz -> { Metadata metadata = clazz.getAnnotation(Metadata.class); if (metadata == null) { return false; } // 检查Metadata注解的flags是否包含合成类标识(第21位) return (metadata.flags() & (1 << 20)) != 0; }) .should().beInterfaces() .orShould().beEnums() .orShould().beDataClasses();
解决方案3:针对性排除WhenMappings类
如果只想排除when表达式生成的映射类,可以直接通过名称中的WhenMappings关键词过滤:
classes() .that().resideInAPackage("shared..") .and().notHaveNameMatching(".*WhenMappings") .should { clazz -> clazz.isInterface || clazz.isEnum || clazz.isDataClass }
内容的提问来源于stack exchange,提问作者JonathanSessenioo
相关产品推荐
相关产品推荐

