Skip to content

Commit 6a95430

Browse files
authored
Merge pull request #1891 from uhafner/only-private-fields
Add a rule to check for non-private instance fields
2 parents f740dc4 + 4ccfef8 commit 6a95430

3 files changed

Lines changed: 24 additions & 2 deletions

File tree

doc/uml/class-diagram-technical.puml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ note "Klasse" as Class
9090
note "Interface" as Interface
9191
note "Vererbung" as Vererbung
9292
note "Implementierung" as Implementierung
93-
note "gerichtete Assoziation" as Assoziation
93+
note "gerichtete Assoziation\n als Objektvariable" as Assoziation
9494
note "Vererbung und dabei\ngenerischen Typ binden" as Generics
9595
note "gerichtete Abhängigkeit:\n<<use>> benutzt\n<<create>> erzeugt\n<<call>> Aufruf" as Dependency
9696
note "Aggregation" as Aggregation

src/test/java/edu/hm/hafner/archunit/ArchitectureRules.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@
3232
* @author Ullrich Hafner
3333
*/
3434
public final class ArchitectureRules {
35+
/** No class should have non-private instance fields. */
36+
public static final ArchRule ONLY_PRIVATE_FIELDS =
37+
fields().that().doNotHaveModifier(JavaModifier.STATIC)
38+
.should().bePrivate().allowEmptyShould(true);
39+
3540
/** Tests should not use fields. Recommendation is to use factory methods for stubs and mocks. */
3641
public static final ArchRule NO_FIELDS_IN_TESTS =
3742
fields().that().areDeclaredInClassesThat().haveSimpleNameEndingWith("Test")

src/test/java/edu/hm/hafner/archunit/ArchitectureRulesTest.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,16 @@
2121
class ArchitectureRulesTest {
2222
private static final String BROKEN_CLASS_NAME = ArchitectureRulesViolatedTest.class.getTypeName();
2323

24+
@Test
25+
void shouldVerifyThatFieldsArePrivate() {
26+
assertThatExceptionOfType(AssertionError.class).isThrownBy(
27+
() -> ArchitectureRules.ONLY_PRIVATE_FIELDS.check(importBrokenClass()))
28+
.withMessageContainingAll(BROKEN_CLASS_NAME, "fields that do not have modifier STATIC should be private' was violated");
29+
30+
assertThatNoException().isThrownBy(
31+
() -> ArchitectureRules.ONLY_PRIVATE_FIELDS.check(importPassingClass()));
32+
}
33+
2434
@Test
2535
void shouldUseProtectedForReadResolve() {
2636
assertThatExceptionOfType(AssertionError.class).isThrownBy(
@@ -100,7 +110,7 @@ void shouldVerifyNoPublicTestMethodsRule() {
100110

101111
private JavaClasses importPassingClass() {
102112
return new ClassFileImporter().importClasses(ArchitectureRulesPassedTest.class,
103-
ArchitectureRulesAlsoPassedTest.class);
113+
ArchitectureRulesAlsoPassedTest.class, ArchitectureRulesPassed.class);
104114
}
105115

106116
private JavaClasses importBrokenClass() {
@@ -117,6 +127,8 @@ public static class ArchitectureRulesViolatedTest {
117127
@edu.umd.cs.findbugs.annotations.Nullable
118128
private final String noNullable = null;
119129

130+
int nonPrivate;
131+
120132
@Test @Disabled("This test is just there to be used in architecture tests")
121133
public void shouldFail() {
122134
org.junit.jupiter.api.Assertions.assertEquals(1, 1);
@@ -188,4 +200,9 @@ protected Object readResolve() {
188200
return this;
189201
}
190202
}
203+
204+
@SuppressWarnings("all") // This class is just there to be used in architecture tests
205+
static class ArchitectureRulesPassed {
206+
private int privateField;
207+
}
191208
}

0 commit comments

Comments
 (0)