【问题标题】:ArchUnit doesnt seem to cache analyzed classesArchUnit 似乎没有缓存分析的类
【发布时间】:2021-01-29 08:57:01
【问题描述】:

我使用 Jupiter 编写了一些 ArchUnit-Tests。我发现了一些例子,你可以使用非静态方法编写 ArchUnit 测试,例如:

@Test
void enforceExceptionNames() {
    classes().that()
             .areAssignableTo(Exception.class)
             .and(modifier(PUBLIC))
             .and().areNotAnnotatedWith("some.qa.ExceptionNameFlaw")
             .should()
             .haveNameMatching(".*Exception").orShould()
             .haveNameMatching(".*Error")
             .check(modulClasses);
}

优点是,你可以做一些不可能是静态的事情——比如在运行时使用反射和其他东西来提取包名。

但是性能很差。大约 1-10 秒,具体取决于大小。

无论哪种方式,ArchUnit 都声明所有类都缓存为静态的。

【问题讨论】:

    标签: java archunit


    【解决方案1】:

    只有在使用 @AnalyzeClasses 和 @ArchTest 注释的静态字段或方法时才会发生缓存。

    将我的测试转换为这种模式后,性能飙升至 0.05 秒!

    @AnalyzeClasses(packages = "some.svc.gui.impl")
    public class StandardCodeModuleTest extends StandardCodeTest {
    
        @ArchTest
        public static final ArchRule ENFORCE_EXCEPTION_NAMES = classes()
                .that()
                .areAssignableTo(Exception.class)
                .and(modifier(PUBLIC))
                .and().areNotAnnotatedWith("some.qa.ExceptionNameFlaw")
                .should()
                .haveNameMatching(".*Exception").orShould()
                .haveNameMatching(".*Error");
    

    【讨论】:

      【解决方案2】:

      您最初的问题没有显示modulClasses 是如何获得的。如果你这样做了

      class StandardCodeModuleTest {
      
          private final JavaClasses modulClasses = new ClassFileImporter().import...
      

      然后(昂贵的)类文件导入将——通常(参见@TestInstance)——为每个测试完成,无需缓存。

      所以是的,将ArchUnit's support for JUnit@AnalyzeClasses 一起使用是完全有意义的,就像you found。但是,@ArchTest 不限于 static 字段或方法。你也可以使用非静态方法:

      @ArchTest
      void enforceExceptionNames(JavaClasses modulClasses) {
          classes().that()
                   .areAssignableTo(Exception.class)
                   .and(modifier(PUBLIC))
                   .and().areNotAnnotatedWith("some.qa.ExceptionNameFlaw")
                   .should()
                   .haveNameMatching(".*Exception").orShould()
                   .haveNameMatching(".*Error")
                   .check(modulClasses);
      }
      

      或非静态ArchRule定义:

      @ArchTest
      ArchRule enforceExceptionNames = classes()
                   .that()
                   .areAssignableTo(Exception.class)
                   .and(modifier(PUBLIC))
                   .and().areNotAnnotatedWith("some.qa.ExceptionNameFlaw")
                   .should()
                   .haveNameMatching(".*Exception").orShould()
                   .haveNameMatching(".*Error");
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-11-02
        • 2021-11-21
        • 2020-02-24
        • 2021-03-25
        • 2012-05-30
        • 1970-01-01
        • 2018-11-10
        • 1970-01-01
        相关资源
        最近更新 更多