Reputation: 71
I wrote some ArchUnit-Tests using Jupiter. I found examples that indicated, you can write your ArchUnit tests using non static methods, like:
@Test
void enforceExceptionNames() {
classes().that()
.areAssignableTo(Exception.class)
.and(modifier(PUBLIC))
.and().areNotAnnotatedWith("some.qa.ExceptionNameFlaw")
.should()
.haveNameMatching(".*Exception").orShould()
.haveNameMatching(".*Error")
.check(modulClasses);
}
The advantage is, that you can do things that arent possible static - like extracting the packagename using reflection at runtime and other stuff.
But performance is poor. Like 1-10 seconds depending on size.
Eitherway ArchUnit states to have all Classes cached static.
Upvotes: 3
Views: 643
Reputation: 3062
Your initial question didn't show how modulClasses
is obtained. If you do
class StandardCodeModuleTest {
private final JavaClasses modulClasses = new ClassFileImporter().import...
then the (expensive) class file import will – usually (cf. @TestInstance) – be done for each test, without caching.
So yes, it totally makes sense to use ArchUnit's support for JUnit with @AnalyzeClasses
, as you found. However, @ArchTest
is not restricted to static fields or methods. You can also use non-static methods:
@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);
}
or non-static ArchRule
definitions:
@ArchTest
ArchRule enforceExceptionNames = classes()
.that()
.areAssignableTo(Exception.class)
.and(modifier(PUBLIC))
.and().areNotAnnotatedWith("some.qa.ExceptionNameFlaw")
.should()
.haveNameMatching(".*Exception").orShould()
.haveNameMatching(".*Error");
Upvotes: 4
Reputation: 71
It semms caching ONLY occurs when using @AnalyzeClasses and @ArchTest annotated static fields or methods.
After transforming my tests to this pattern, performance skyrockets to 0.05 seconds!
@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");
Upvotes: 3