2

我使用 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 都声明所有类都缓存为静态的。

4

2 回答 2

2

它仅在使用 @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");
于 2021-01-29T09:01:17.297 回答
2

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

class StandardCodeModuleTest {

    private final JavaClasses modulClasses = new ClassFileImporter().import...

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

所以是的,正如您所发现的,将ArchUnit 对 JUnit 的支持与.一起使用是完全有意义的。但是,不限于静态字段或方法。您还可以使用非静态方法:@AnalyzeClasses@ArchTest

@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");
于 2021-02-11T07:36:42.843 回答