From 6ac09612406ba45fed52e4eb9cd5cd757a506e91 Mon Sep 17 00:00:00 2001
From: DanielOber <145556033+DanielOber@users.noreply.github.com>
Date: Fri, 12 Sep 2025 14:36:44 +0200
Subject: [PATCH 1/6] added archunit and fixed tests
---
refarch-backend/pom.xml | 6 +++
.../refarch/archunit/ArchUnitTest.java | 42 +++++++++++++++++++
.../refarch/archunit/rules/MethodRules.java | 41 ++++++++++++++++++
.../TestClassesEndWithTestCondition.java | 37 ++++++++++++++++
.../filter/CacheControlFilterTest.java | 2 +-
.../UnicodeFilterConfigurationTest.java | 2 +-
.../filter/nfcconverter/NfcConverterTest.java | 4 +-
.../filter/nfcconverter/NfcHelperTest.java | 12 +++---
...KeycloakRolesAuthoritiesConverterTest.java | 8 ++--
.../UserInfoAuthoritiesConverterTest.java | 6 +--
10 files changed, 143 insertions(+), 17 deletions(-)
create mode 100644 refarch-backend/src/test/java/de/muenchen/refarch/archunit/ArchUnitTest.java
create mode 100644 refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/MethodRules.java
create mode 100644 refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/TestClassesEndWithTestCondition.java
diff --git a/refarch-backend/pom.xml b/refarch-backend/pom.xml
index 5b78de35e..76ace2bc8 100644
--- a/refarch-backend/pom.xml
+++ b/refarch-backend/pom.xml
@@ -58,6 +58,7 @@
0.8.13
+ 1.4.1
3.1.1
@@ -259,6 +260,11 @@
spring-boot-configuration-processor
true
+
+ com.tngtech.archunit
+ archunit
+ ${archunit.version}
+
diff --git a/refarch-backend/src/test/java/de/muenchen/refarch/archunit/ArchUnitTest.java b/refarch-backend/src/test/java/de/muenchen/refarch/archunit/ArchUnitTest.java
new file mode 100644
index 000000000..dd67bb627
--- /dev/null
+++ b/refarch-backend/src/test/java/de/muenchen/refarch/archunit/ArchUnitTest.java
@@ -0,0 +1,42 @@
+package de.muenchen.refarch.archunit;
+
+import com.tngtech.archunit.core.domain.JavaClasses;
+import com.tngtech.archunit.core.importer.ClassFileImporter;
+import com.tngtech.archunit.core.importer.ImportOption;
+import com.tngtech.archunit.lang.ArchRule;
+import de.muenchen.refarch.archunit.rules.MethodRules;
+import java.util.stream.Stream;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.aggregator.ArgumentsAccessor;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+public class ArchUnitTest {
+
+ private static JavaClasses allTestClasses;
+
+ @BeforeAll
+ static void init() {
+ allTestClasses = new ClassFileImporter()
+ .withImportOption(new ImportOption.OnlyIncludeTests())
+ .importPackages(de.muenchen.refarch.MicroServiceApplication.class.getPackage().getName());
+ }
+
+ @ParameterizedTest(name = "{0}")
+ @MethodSource("allTestClassesRulesToVerify")
+ void givenAllArchUnitRulesForAllTestClasses_thenRunArchUnitTests(final ArgumentsAccessor arguments) {
+ arguments.get(1, ArchRule.class).check(allTestClasses);
+ }
+
+ public static Stream allTestClassesRulesToVerify() {
+ return Stream.of(
+ Arguments.of("RULE_TESTCLASSES_END_WITH_TEST_CONVENTION_MATCHED",
+ MethodRules.RULE_TESTCLASSES_END_WITH_TEST_CONVENTION_MATCHED),
+ Arguments.of("TEST_NAMING_CONVENTION_RULE", MethodRules.RULE_TEST_NAMING_CONVENTION_SHOULD_WHEN_MATCHED),
+ Arguments.of("RULE_BEFORE_EACH_NAMING_CONVENTION_MATCHED", MethodRules.RULE_BEFORE_EACH_NAMING_CONVENTION_MATCHED),
+ Arguments.of("RULE_AFTER_EACH_NAMING_CONVENTION_MATCHED", MethodRules.RULE_AFTER_EACH_NAMING_CONVENTION_MATCHED),
+ Arguments.of("TEST_METHODS_ARE_PACKAGE_PRIVATE_CONVENTION_MATCHED", MethodRules.RULE_TEST_METHODS_ARE_PACKAGE_PRIVATE_CONVENTION_MATCHED));
+ }
+
+}
diff --git a/refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/MethodRules.java b/refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/MethodRules.java
new file mode 100644
index 000000000..e8172f7de
--- /dev/null
+++ b/refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/MethodRules.java
@@ -0,0 +1,41 @@
+package de.muenchen.refarch.archunit.rules;
+
+import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.methods;
+import static de.muenchen.refarch.archunit.rules.TestClassesEndWithTestCondition.haveTopEnclosingClassEndingWithTest;
+
+import com.tngtech.archunit.core.domain.JavaModifier;
+import com.tngtech.archunit.lang.ArchRule;
+import com.tngtech.archunit.lang.syntax.elements.MethodsShouldConjunction;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class MethodRules {
+
+ public static final MethodsShouldConjunction RULE_TEST_NAMING_CONVENTION_SHOULD_WHEN_MATCHED = methods()
+ .that().areAnnotatedWith(Test.class).or().areAnnotatedWith(ParameterizedTest.class)
+ .should().haveNameMatching("^given[A-Z][a-zA-Z]+_then[A-Z][a-zA-Z]+$$$$$");
+
+ public static final ArchRule RULE_BEFORE_EACH_NAMING_CONVENTION_MATCHED = methods()
+ .that().areAnnotatedWith(BeforeEach.class).should().haveNameMatching("setUp")
+ .allowEmptyShould(true);
+
+ public static final ArchRule RULE_AFTER_EACH_NAMING_CONVENTION_MATCHED = methods()
+ .that().areAnnotatedWith(AfterEach.class).should().haveNameMatching("tearDown")
+ .allowEmptyShould(true);
+
+ public static final ArchRule RULE_TEST_METHODS_ARE_PACKAGE_PRIVATE_CONVENTION_MATCHED = methods()
+ .that().areAnnotatedWith(Test.class).or().areAnnotatedWith(ParameterizedTest.class).should()
+ .notHaveModifier(JavaModifier.PROTECTED)
+ .andShould().notHaveModifier(JavaModifier.PRIVATE)
+ .andShould().notHaveModifier(JavaModifier.PUBLIC);
+
+ public static final ArchRule RULE_TESTCLASSES_END_WITH_TEST_CONVENTION_MATCHED = methods()
+ .that().areAnnotatedWith(Test.class).or().areAnnotatedWith(ParameterizedTest.class)
+ .should(haveTopEnclosingClassEndingWithTest);
+}
diff --git a/refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/TestClassesEndWithTestCondition.java b/refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/TestClassesEndWithTestCondition.java
new file mode 100644
index 000000000..a60faaeb5
--- /dev/null
+++ b/refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/TestClassesEndWithTestCondition.java
@@ -0,0 +1,37 @@
+package de.muenchen.refarch.archunit.rules;
+
+import com.tngtech.archunit.core.domain.JavaClass;
+import com.tngtech.archunit.core.domain.JavaMethod;
+import com.tngtech.archunit.lang.ArchCondition;
+import com.tngtech.archunit.lang.ConditionEvents;
+import com.tngtech.archunit.lang.SimpleConditionEvent;
+import java.util.Optional;
+
+public class TestClassesEndWithTestCondition extends ArchCondition {
+
+ TestClassesEndWithTestCondition() {
+ super("have top enclosing class name ending with `Test`");
+ }
+
+ public static final ArchCondition haveTopEnclosingClassEndingWithTest = new TestClassesEndWithTestCondition();
+
+ @Override
+ public void check(JavaMethod method, ConditionEvents events) {
+ var topEnclosingClass = getTopEnclosingClass(method.getOwner());
+
+ if (topEnclosingClass.isPresent() && !topEnclosingClass.get().getFullName().endsWith("Test")) {
+ events.add(SimpleConditionEvent.violated(method, "test " + method.getName() + " is not inside of test class"));
+ }
+ }
+
+ private Optional getTopEnclosingClass(JavaClass item) {
+ JavaClass enclosingClass = null;
+ while (item.getEnclosingClass().isPresent()) {
+ item = item.getEnclosingClass().orElseThrow();
+ enclosingClass = item;
+ }
+
+ enclosingClass = enclosingClass == null ? item : enclosingClass;
+ return Optional.of(enclosingClass);
+ }
+}
diff --git a/refarch-backend/src/test/java/de/muenchen/refarch/configuration/filter/CacheControlFilterTest.java b/refarch-backend/src/test/java/de/muenchen/refarch/configuration/filter/CacheControlFilterTest.java
index fad824e4d..9c0bef952 100644
--- a/refarch-backend/src/test/java/de/muenchen/refarch/configuration/filter/CacheControlFilterTest.java
+++ b/refarch-backend/src/test/java/de/muenchen/refarch/configuration/filter/CacheControlFilterTest.java
@@ -44,7 +44,7 @@ class CacheControlFilterTest {
private TestRestTemplate testRestTemplate;
@Test
- void testForCacheControlHeadersForEntityEndpoint() {
+ void givenEntityEndpoint_thenCacheControlHeadersPresent() {
final ResponseEntity response = testRestTemplate.exchange(ENTITY_ENDPOINT_URL, HttpMethod.GET, null, String.class);
assertEquals(HttpStatus.OK, response.getStatusCode());
assertTrue(response.getHeaders().containsKey(HttpHeaders.CACHE_CONTROL));
diff --git a/refarch-backend/src/test/java/de/muenchen/refarch/configuration/filter/UnicodeFilterConfigurationTest.java b/refarch-backend/src/test/java/de/muenchen/refarch/configuration/filter/UnicodeFilterConfigurationTest.java
index ba3cea914..fb7fd0b4e 100644
--- a/refarch-backend/src/test/java/de/muenchen/refarch/configuration/filter/UnicodeFilterConfigurationTest.java
+++ b/refarch-backend/src/test/java/de/muenchen/refarch/configuration/filter/UnicodeFilterConfigurationTest.java
@@ -58,7 +58,7 @@ class UnicodeFilterConfigurationTest {
private TheEntityRepository theEntityRepository;
@Test
- void testForNfcNormalization() {
+ void givenDecomposedString_thenCovertToNfcNormalized() {
// Given
// Persist entity with decomposed string.
final TheEntityRequestDTO theEntityRequestDto = new TheEntityRequestDTO(TEXT_ATTRIBUTE_DECOMPOSED);
diff --git a/refarch-backend/src/test/java/de/muenchen/refarch/configuration/filter/nfcconverter/NfcConverterTest.java b/refarch-backend/src/test/java/de/muenchen/refarch/configuration/filter/nfcconverter/NfcConverterTest.java
index e0ec0a0d4..5025bcff6 100644
--- a/refarch-backend/src/test/java/de/muenchen/refarch/configuration/filter/nfcconverter/NfcConverterTest.java
+++ b/refarch-backend/src/test/java/de/muenchen/refarch/configuration/filter/nfcconverter/NfcConverterTest.java
@@ -70,7 +70,7 @@ class NfcConverterTest {
// Test that request with configured ContentType is normalized to NFC.
@Test
- void testFilterIfContenttypeInWhitelist() throws ServletException, IOException {
+ void givenContenttypeInWhitelist_thenFilter() throws ServletException, IOException {
mockRequest("text/plain");
filter.doFilter(req, resp, chain);
@@ -90,7 +90,7 @@ void testFilterIfContenttypeInWhitelist() throws ServletException, IOException {
// Test that Request not configured ContentType remains unchanged, i.e. is not normalized to NFC.
@Test
- void testSkipFilterIfContenttypeNotInWhitelist() throws ServletException, IOException {
+ void givenContenttypeNotInWhitelist_thenSkipFilter() throws ServletException, IOException {
mockRequest("application/notvalid");
filter.doFilter(req, resp, chain);
diff --git a/refarch-backend/src/test/java/de/muenchen/refarch/configuration/filter/nfcconverter/NfcHelperTest.java b/refarch-backend/src/test/java/de/muenchen/refarch/configuration/filter/nfcconverter/NfcHelperTest.java
index 9c13e92a5..22aa1d327 100644
--- a/refarch-backend/src/test/java/de/muenchen/refarch/configuration/filter/nfcconverter/NfcHelperTest.java
+++ b/refarch-backend/src/test/java/de/muenchen/refarch/configuration/filter/nfcconverter/NfcHelperTest.java
@@ -29,7 +29,7 @@ class NfcHelperTest {
private static final String[] NFC_OUTPUT_EXPECTED = { FIRST_NFC, SECOND_NFC, THIRD_NFC };
@Test
- void nfcConverterString() {
+ void givenString_thenNfcConverted() {
assertEquals(FIRST_NFC, NfcHelper.nfcConverter(FIRST_NFD));
assertEquals(FIRST_NFC.length(), NfcHelper.nfcConverter(FIRST_NFD).length());
@@ -41,7 +41,7 @@ void nfcConverterString() {
}
@Test
- void nfcConverterStringBuffer() {
+ void givenStringBuffer_thenNfcConverted() {
assertEquals(FIRST_NFC, NfcHelper.nfcConverter(new StringBuffer(FIRST_NFD)).toString());
assertEquals(FIRST_NFC.length(), NfcHelper.nfcConverter(new StringBuffer(FIRST_NFD)).length());
@@ -53,13 +53,13 @@ void nfcConverterStringBuffer() {
}
@Test
- void nfcConverterStringArray() {
+ void givenStringArray_thenNfcConverted() {
assertArrayEquals(NFC_OUTPUT_EXPECTED, NfcHelper.nfcConverter(NFD_INPUT));
assertEquals(NFC_OUTPUT_EXPECTED.length, NfcHelper.nfcConverter(NFD_INPUT).length);
}
@Test
- void nfcConverterMapOfStrings() {
+ void givenMapOfStrings_thenNfcConverted() {
final Map nfdInput = new HashMap<>();
nfdInput.put(FIRST_NFD, NFD_INPUT);
nfdInput.put(SECOND_NFD, NFD_INPUT);
@@ -73,7 +73,7 @@ void nfcConverterMapOfStrings() {
}
@Test
- void nfcConverterCookie() {
+ void givenCookie_thenNfcConverted() {
final Cookie nfcCookie = NfcHelper.nfcConverter(createNfdCookie());
assertEquals(NfcConverterTest.TOKEN, nfcCookie.getName());
@@ -84,7 +84,7 @@ void nfcConverterCookie() {
@SuppressWarnings("PMD.UnitTestShouldIncludeAssert")
@Test
- void nfcConverterCookieArray() {
+ void givenCookieArray_thenNfcConverted() {
final Cookie[] nfdCookies = Collections.nCopies(3, createNfdCookie()).toArray(new Cookie[3]);
final Cookie[] nfcCookies = NfcHelper.nfcConverter(nfdCookies);
Arrays.asList(nfcCookies).forEach(nfcCookie -> {
diff --git a/refarch-backend/src/test/java/de/muenchen/refarch/configuration/security/KeycloakRolesAuthoritiesConverterTest.java b/refarch-backend/src/test/java/de/muenchen/refarch/configuration/security/KeycloakRolesAuthoritiesConverterTest.java
index a3a00ba75..5ec646282 100644
--- a/refarch-backend/src/test/java/de/muenchen/refarch/configuration/security/KeycloakRolesAuthoritiesConverterTest.java
+++ b/refarch-backend/src/test/java/de/muenchen/refarch/configuration/security/KeycloakRolesAuthoritiesConverterTest.java
@@ -36,7 +36,7 @@ void setUp() {
}
@Test
- void testConvert_WithRoles() {
+ void givenRoles_thenConvert() {
// Setup
final Map resourceAccessClaim = new HashMap<>();
resourceAccessClaim.put(TEST_CLIENT, Map.of("roles", List.of("admin", "user")));
@@ -54,7 +54,7 @@ void testConvert_WithRoles() {
}
@Test
- void testConvert_WithoutRoles() {
+ void givenNoRoles_thenConvert() {
// Setup
final Map claims = new HashMap<>();
claims.put(RESOURCE_ACCESS_CLAIM, Map.of(
@@ -71,7 +71,7 @@ void testConvert_WithoutRoles() {
}
@Test
- void testConvert_ClientNotInResourceAccess() {
+ void givenClientNotInResourceAccess_thenConvert() {
// Setup
final Map resourceAccessClaim = new HashMap<>();
resourceAccessClaim.put("other-client", Map.of("roles", List.of("admin")));
@@ -87,7 +87,7 @@ void testConvert_ClientNotInResourceAccess() {
}
@Test
- void testConvert_NullClaims() {
+ void givenNullClaims_thenConvert() {
// Setup
final Jwt jwt = mock(Jwt.class);
diff --git a/refarch-backend/src/test/java/de/muenchen/refarch/configuration/security/UserInfoAuthoritiesConverterTest.java b/refarch-backend/src/test/java/de/muenchen/refarch/configuration/security/UserInfoAuthoritiesConverterTest.java
index fb718fdb4..11f0e7c47 100644
--- a/refarch-backend/src/test/java/de/muenchen/refarch/configuration/security/UserInfoAuthoritiesConverterTest.java
+++ b/refarch-backend/src/test/java/de/muenchen/refarch/configuration/security/UserInfoAuthoritiesConverterTest.java
@@ -48,7 +48,7 @@ void setUp() {
}
@Test
- void testConvert_WithAuthorities() {
+ void givenNoRoles_thenConvert() {
// Setup
final Jwt jwt = mock(Jwt.class);
when(jwt.getSubject()).thenReturn(TEST_SUBJECT);
@@ -70,7 +70,7 @@ void testConvert_WithAuthorities() {
}
@Test
- void testConvert_NoAuthorities() {
+ void givenNoAuthorities_thenConvert() {
// Setup
final Jwt jwt = mock(Jwt.class);
when(jwt.getSubject()).thenReturn(TEST_SUBJECT);
@@ -89,7 +89,7 @@ void testConvert_NoAuthorities() {
}
@Test
- void testConvert_CacheHit() {
+ void givenCacheHit_thenConvert() {
// Setup
final Jwt jwt = mock(Jwt.class);
when(jwt.getSubject()).thenReturn(TEST_SUBJECT);
From 8bcf652a9e0bf8c057a769e5556ea79cd61d671f Mon Sep 17 00:00:00 2001
From: DanielOber <145556033+DanielOber@users.noreply.github.com>
Date: Mon, 15 Sep 2025 14:05:59 +0200
Subject: [PATCH 2/6] spotless
---
.../java/de/muenchen/refarch/archunit/rules/MethodRules.java | 1 -
1 file changed, 1 deletion(-)
diff --git a/refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/MethodRules.java b/refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/MethodRules.java
index e8172f7de..f1cf860c2 100644
--- a/refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/MethodRules.java
+++ b/refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/MethodRules.java
@@ -12,7 +12,6 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
-import org.springframework.web.bind.annotation.RequestMapping;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class MethodRules {
From 41d5b5cd8ece972da7e030d51d899da0efb55616 Mon Sep 17 00:00:00 2001
From: DanielOber <145556033+DanielOber@users.noreply.github.com>
Date: Mon, 15 Sep 2025 14:34:51 +0200
Subject: [PATCH 3/6] code rabbit review
---
refarch-backend/pom.xml | 1 +
.../refarch/archunit/rules/MethodRules.java | 4 ++--
.../rules/TestClassesEndWithTestCondition.java | 14 +++++---------
3 files changed, 8 insertions(+), 11 deletions(-)
diff --git a/refarch-backend/pom.xml b/refarch-backend/pom.xml
index 76ace2bc8..85c2efee7 100644
--- a/refarch-backend/pom.xml
+++ b/refarch-backend/pom.xml
@@ -264,6 +264,7 @@
com.tngtech.archunit
archunit
${archunit.version}
+ test
diff --git a/refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/MethodRules.java b/refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/MethodRules.java
index f1cf860c2..1d601b2a3 100644
--- a/refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/MethodRules.java
+++ b/refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/MethodRules.java
@@ -14,11 +14,11 @@
import org.junit.jupiter.params.ParameterizedTest;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public class MethodRules {
+public final class MethodRules {
public static final MethodsShouldConjunction RULE_TEST_NAMING_CONVENTION_SHOULD_WHEN_MATCHED = methods()
.that().areAnnotatedWith(Test.class).or().areAnnotatedWith(ParameterizedTest.class)
- .should().haveNameMatching("^given[A-Z][a-zA-Z]+_then[A-Z][a-zA-Z]+$$$$$");
+ .should().haveNameMatching("^given[A-Z][a-zA-Z]+_then[A-Z][a-zA-Z]+$");
public static final ArchRule RULE_BEFORE_EACH_NAMING_CONVENTION_MATCHED = methods()
.that().areAnnotatedWith(BeforeEach.class).should().haveNameMatching("setUp")
diff --git a/refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/TestClassesEndWithTestCondition.java b/refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/TestClassesEndWithTestCondition.java
index a60faaeb5..5703a72ba 100644
--- a/refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/TestClassesEndWithTestCondition.java
+++ b/refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/TestClassesEndWithTestCondition.java
@@ -5,7 +5,6 @@
import com.tngtech.archunit.lang.ArchCondition;
import com.tngtech.archunit.lang.ConditionEvents;
import com.tngtech.archunit.lang.SimpleConditionEvent;
-import java.util.Optional;
public class TestClassesEndWithTestCondition extends ArchCondition {
@@ -19,19 +18,16 @@ public class TestClassesEndWithTestCondition extends ArchCondition {
public void check(JavaMethod method, ConditionEvents events) {
var topEnclosingClass = getTopEnclosingClass(method.getOwner());
- if (topEnclosingClass.isPresent() && !topEnclosingClass.get().getFullName().endsWith("Test")) {
- events.add(SimpleConditionEvent.violated(method, "test " + method.getName() + " is not inside of test class"));
+ if (!topEnclosingClass.getName().endsWith("Test")) {
+ events.add(SimpleConditionEvent.violated(method, "Method %s must be declared in a class whose simple name ends with 'Test' (found: %s)"
+ .formatted(method.getName(), topEnclosingClass.getSimpleName())));
}
}
- private Optional getTopEnclosingClass(JavaClass item) {
- JavaClass enclosingClass = null;
+ private JavaClass getTopEnclosingClass(JavaClass item) {
while (item.getEnclosingClass().isPresent()) {
item = item.getEnclosingClass().orElseThrow();
- enclosingClass = item;
}
-
- enclosingClass = enclosingClass == null ? item : enclosingClass;
- return Optional.of(enclosingClass);
+ return item;
}
}
From 6ba6a2bec50208a80376d9285aa4e1b28d1a396e Mon Sep 17 00:00:00 2001
From: DanielOber <145556033+DanielOber@users.noreply.github.com>
Date: Mon, 15 Sep 2025 16:22:52 +0200
Subject: [PATCH 4/6] code rabbit review
---
.../java/de/muenchen/refarch/archunit/rules/MethodRules.java | 3 +--
.../archunit/rules/TestClassesEndWithTestCondition.java | 4 ++--
2 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/MethodRules.java b/refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/MethodRules.java
index 1d601b2a3..ad9123b57 100644
--- a/refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/MethodRules.java
+++ b/refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/MethodRules.java
@@ -5,7 +5,6 @@
import com.tngtech.archunit.core.domain.JavaModifier;
import com.tngtech.archunit.lang.ArchRule;
-import com.tngtech.archunit.lang.syntax.elements.MethodsShouldConjunction;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.junit.jupiter.api.AfterEach;
@@ -16,7 +15,7 @@
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class MethodRules {
- public static final MethodsShouldConjunction RULE_TEST_NAMING_CONVENTION_SHOULD_WHEN_MATCHED = methods()
+ public static final ArchRule RULE_TEST_NAMING_CONVENTION_SHOULD_WHEN_MATCHED = methods()
.that().areAnnotatedWith(Test.class).or().areAnnotatedWith(ParameterizedTest.class)
.should().haveNameMatching("^given[A-Z][a-zA-Z]+_then[A-Z][a-zA-Z]+$");
diff --git a/refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/TestClassesEndWithTestCondition.java b/refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/TestClassesEndWithTestCondition.java
index 5703a72ba..a6975fdfb 100644
--- a/refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/TestClassesEndWithTestCondition.java
+++ b/refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/TestClassesEndWithTestCondition.java
@@ -16,9 +16,9 @@ public class TestClassesEndWithTestCondition extends ArchCondition {
@Override
public void check(JavaMethod method, ConditionEvents events) {
- var topEnclosingClass = getTopEnclosingClass(method.getOwner());
+ final var topEnclosingClass = getTopEnclosingClass(method.getOwner());
- if (!topEnclosingClass.getName().endsWith("Test")) {
+ if (!topEnclosingClass.getSimpleName().endsWith("Test")) {
events.add(SimpleConditionEvent.violated(method, "Method %s must be declared in a class whose simple name ends with 'Test' (found: %s)"
.formatted(method.getName(), topEnclosingClass.getSimpleName())));
}
From 564bca9c0f7be56bde396c46329e738f41cbe5fa Mon Sep 17 00:00:00 2001
From: DanielOber <145556033+DanielOber@users.noreply.github.com>
Date: Thu, 18 Sep 2025 15:24:11 +0200
Subject: [PATCH 5/6] renaming
---
.../de/muenchen/refarch/archunit/ArchUnitTest.java | 12 ++++++------
.../archunit/rules/{MethodRules.java => Rules.java} | 4 ++--
2 files changed, 8 insertions(+), 8 deletions(-)
rename refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/{MethodRules.java => Rules.java} (93%)
diff --git a/refarch-backend/src/test/java/de/muenchen/refarch/archunit/ArchUnitTest.java b/refarch-backend/src/test/java/de/muenchen/refarch/archunit/ArchUnitTest.java
index dd67bb627..88c63b195 100644
--- a/refarch-backend/src/test/java/de/muenchen/refarch/archunit/ArchUnitTest.java
+++ b/refarch-backend/src/test/java/de/muenchen/refarch/archunit/ArchUnitTest.java
@@ -4,7 +4,7 @@
import com.tngtech.archunit.core.importer.ClassFileImporter;
import com.tngtech.archunit.core.importer.ImportOption;
import com.tngtech.archunit.lang.ArchRule;
-import de.muenchen.refarch.archunit.rules.MethodRules;
+import de.muenchen.refarch.archunit.rules.Rules;
import java.util.stream.Stream;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest;
@@ -32,11 +32,11 @@ void givenAllArchUnitRulesForAllTestClasses_thenRunArchUnitTests(final Arguments
public static Stream allTestClassesRulesToVerify() {
return Stream.of(
Arguments.of("RULE_TESTCLASSES_END_WITH_TEST_CONVENTION_MATCHED",
- MethodRules.RULE_TESTCLASSES_END_WITH_TEST_CONVENTION_MATCHED),
- Arguments.of("TEST_NAMING_CONVENTION_RULE", MethodRules.RULE_TEST_NAMING_CONVENTION_SHOULD_WHEN_MATCHED),
- Arguments.of("RULE_BEFORE_EACH_NAMING_CONVENTION_MATCHED", MethodRules.RULE_BEFORE_EACH_NAMING_CONVENTION_MATCHED),
- Arguments.of("RULE_AFTER_EACH_NAMING_CONVENTION_MATCHED", MethodRules.RULE_AFTER_EACH_NAMING_CONVENTION_MATCHED),
- Arguments.of("TEST_METHODS_ARE_PACKAGE_PRIVATE_CONVENTION_MATCHED", MethodRules.RULE_TEST_METHODS_ARE_PACKAGE_PRIVATE_CONVENTION_MATCHED));
+ Rules.RULE_TESTCLASSES_END_WITH_TEST_CONVENTION_MATCHED),
+ Arguments.of("TEST_NAMING_CONVENTION_RULE", Rules.RULE_TEST_NAMING_CONVENTION_GIVEN_THEN_MATCHED),
+ Arguments.of("RULE_BEFORE_EACH_NAMING_CONVENTION_MATCHED", Rules.RULE_BEFORE_EACH_NAMING_CONVENTION_MATCHED),
+ Arguments.of("RULE_AFTER_EACH_NAMING_CONVENTION_MATCHED", Rules.RULE_AFTER_EACH_NAMING_CONVENTION_MATCHED),
+ Arguments.of("TEST_METHODS_ARE_PACKAGE_PRIVATE_CONVENTION_MATCHED", Rules.RULE_TEST_METHODS_ARE_PACKAGE_PRIVATE_CONVENTION_MATCHED));
}
}
diff --git a/refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/MethodRules.java b/refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/Rules.java
similarity index 93%
rename from refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/MethodRules.java
rename to refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/Rules.java
index ad9123b57..849db8182 100644
--- a/refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/MethodRules.java
+++ b/refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/Rules.java
@@ -13,9 +13,9 @@
import org.junit.jupiter.params.ParameterizedTest;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public final class MethodRules {
+public final class Rules {
- public static final ArchRule RULE_TEST_NAMING_CONVENTION_SHOULD_WHEN_MATCHED = methods()
+ public static final ArchRule RULE_TEST_NAMING_CONVENTION_GIVEN_THEN_MATCHED = methods()
.that().areAnnotatedWith(Test.class).or().areAnnotatedWith(ParameterizedTest.class)
.should().haveNameMatching("^given[A-Z][a-zA-Z]+_then[A-Z][a-zA-Z]+$");
From 8cc94f3f18f8de95a232c7e5dd38ab55b3d16880 Mon Sep 17 00:00:00 2001
From: DanielOber <145556033+DanielOber@users.noreply.github.com>
Date: Fri, 10 Oct 2025 13:32:54 +0200
Subject: [PATCH 6/6] coderabbit review eingearbeitet
---
.../refarch/archunit/rules/Rules.java | 22 ++++++++++++++-----
1 file changed, 17 insertions(+), 5 deletions(-)
diff --git a/refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/Rules.java b/refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/Rules.java
index 849db8182..713b9fb6b 100644
--- a/refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/Rules.java
+++ b/refarch-backend/src/test/java/de/muenchen/refarch/archunit/rules/Rules.java
@@ -9,31 +9,43 @@
import lombok.NoArgsConstructor;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.RepeatedTest;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestTemplate;
import org.junit.jupiter.params.ParameterizedTest;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class Rules {
public static final ArchRule RULE_TEST_NAMING_CONVENTION_GIVEN_THEN_MATCHED = methods()
- .that().areAnnotatedWith(Test.class).or().areAnnotatedWith(ParameterizedTest.class)
+ .that().areAnnotatedWith(Test.class)
+ .or().areAnnotatedWith(ParameterizedTest.class)
+ .or().areAnnotatedWith(RepeatedTest.class)
+ .or()
+ .areAnnotatedWith(TestTemplate.class)
.should().haveNameMatching("^given[A-Z][a-zA-Z]+_then[A-Z][a-zA-Z]+$");
public static final ArchRule RULE_BEFORE_EACH_NAMING_CONVENTION_MATCHED = methods()
- .that().areAnnotatedWith(BeforeEach.class).should().haveNameMatching("setUp")
+ .that().areAnnotatedWith(BeforeEach.class).should().haveNameMatching("^setUp$")
.allowEmptyShould(true);
public static final ArchRule RULE_AFTER_EACH_NAMING_CONVENTION_MATCHED = methods()
- .that().areAnnotatedWith(AfterEach.class).should().haveNameMatching("tearDown")
+ .that().areAnnotatedWith(AfterEach.class).should().haveNameMatching("^tearDown$")
.allowEmptyShould(true);
public static final ArchRule RULE_TEST_METHODS_ARE_PACKAGE_PRIVATE_CONVENTION_MATCHED = methods()
- .that().areAnnotatedWith(Test.class).or().areAnnotatedWith(ParameterizedTest.class).should()
+ .that().areAnnotatedWith(Test.class)
+ .or().areAnnotatedWith(ParameterizedTest.class)
+ .or().areAnnotatedWith(RepeatedTest.class).or()
+ .areAnnotatedWith(TestTemplate.class).should()
.notHaveModifier(JavaModifier.PROTECTED)
.andShould().notHaveModifier(JavaModifier.PRIVATE)
.andShould().notHaveModifier(JavaModifier.PUBLIC);
public static final ArchRule RULE_TESTCLASSES_END_WITH_TEST_CONVENTION_MATCHED = methods()
- .that().areAnnotatedWith(Test.class).or().areAnnotatedWith(ParameterizedTest.class)
+ .that().areAnnotatedWith(Test.class)
+ .or().areAnnotatedWith(ParameterizedTest.class)
+ .or().areAnnotatedWith(RepeatedTest.class).or()
+ .areAnnotatedWith(TestTemplate.class)
.should(haveTopEnclosingClassEndingWithTest);
}