Skip to content

Commit 6f99640

Browse files
authored
Add instance methods check (#2)
1 parent fd954c0 commit 6f99640

File tree

7 files changed

+155
-5
lines changed

7 files changed

+155
-5
lines changed

gradle.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ POM_NAME=UtilsVerifier
22
POM_ARTIFACT_ID=utilsverifier
33
POM_PACKAGING=jar
44

5-
VERSION_NAME=0.0.1-SNAPSHOT
6-
VERSION_CODE=1
5+
VERSION_NAME=0.0.2-SNAPSHOT
6+
VERSION_CODE=2
77
GROUP=com.github.karczews
88

99
POM_DESCRIPTION=UtilsVerifier can be used in JUnit 4 unit tests to verify whether given util class is well formed one.

src/main/java/com/github/karczews/utilsverifier/UtilsVerifier.java

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import java.lang.reflect.Constructor;
1616
import java.lang.reflect.Field;
1717
import java.lang.reflect.InvocationTargetException;
18+
import java.lang.reflect.Method;
1819
import java.lang.reflect.Modifier;
1920

2021
/**
@@ -39,6 +40,7 @@ public class UtilsVerifier<T> {
3940
private boolean suppressOnlyOneConstructorCheck = false;
4041
private boolean suppressPrivateConstructorCheck = false;
4142
private boolean suppressInstanceFieldCheck = false;
43+
private boolean suppressInstanceMethodCheck = false;
4244

4345
private UtilsVerifier(final Class<T> type) {
4446
classUnderTest = type;
@@ -62,6 +64,7 @@ public void verify() {
6264
hasOnlyOneConstructor();
6365
verifyPrivateConstructor();
6466
hasNoInstanceFields();
67+
hasNoInstanceMethods();
6568
}
6669

6770
/**
@@ -117,6 +120,17 @@ public UtilsVerifier<T> suppressInstanceFieldCheck(final boolean suppressCheck)
117120
return this;
118121
}
119122

123+
/**
124+
* Suppress instance method verification.
125+
* Use if util class is allowed to have instance methods.
126+
*
127+
* @param suppressCheck true if check should be suppressed, false otherwise
128+
*/
129+
public UtilsVerifier<T> suppressInstanceMethodCheck(final boolean suppressCheck) {
130+
suppressInstanceMethodCheck = suppressCheck;
131+
return this;
132+
}
133+
120134
private void checkIfClassIsFinal() {
121135
if (suppressFinalClassCheck) return;
122136
if (!Modifier.isFinal(classUnderTest.getModifiers())) {
@@ -164,10 +178,22 @@ private void hasNoInstanceFields() {
164178
for (int index = 0; index < fields.length; index++) {
165179
final Field field = fields[index];
166180
if (!Modifier.isStatic(field.getModifiers())) {
167-
throw new AssertionError(classUnderTest.getName() + " contains instance field " + field.getName());
181+
throw new AssertionError(classUnderTest.getName()
182+
+ " contains instance field " + field.getName());
183+
}
184+
}
185+
}
186+
187+
private void hasNoInstanceMethods() {
188+
if (suppressInstanceMethodCheck) return;
189+
final Method[] methods = classUnderTest.getDeclaredMethods();
190+
for (int index = 0; index < methods.length; index++) {
191+
final Method method = methods[index];
192+
if (!Modifier.isStatic(method.getModifiers())) {
193+
throw new AssertionError(classUnderTest.getName()
194+
+ " contains instance method " + method.getName());
168195
}
169196
}
170197
}
171-
//TODO: add check for non-static methods
172198
//TODO: add check for mutable static fields
173199
}

src/test/java/com/github/karczews/utilsverifier/UtilsVerifierTest.java

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,25 @@
1313
package com.github.karczews.utilsverifier;
1414

1515

16+
import com.github.karczews.utilsverifier.subjects.AbstractClass;
17+
import com.github.karczews.utilsverifier.subjects.DefaultConstructor;
1618
import com.github.karczews.utilsverifier.subjects.InstanceFields;
19+
import com.github.karczews.utilsverifier.subjects.InstanceMethods;
1720
import com.github.karczews.utilsverifier.subjects.MultipleConstructors;
1821
import com.github.karczews.utilsverifier.subjects.NonFinalClass;
22+
import com.github.karczews.utilsverifier.subjects.NonPrivateConstructor;
1923
import com.github.karczews.utilsverifier.subjects.ThrowingConstructor;
2024
import com.github.karczews.utilsverifier.subjects.WellFormed;
2125

2226
import org.junit.Rule;
2327
import org.junit.Test;
2428
import org.junit.rules.ExpectedException;
29+
import org.mockito.Mockito;
2530

2631
import static org.hamcrest.core.AllOf.allOf;
2732
import static org.hamcrest.core.StringContains.containsString;
33+
import static org.mockito.Mockito.mock;
34+
import static org.mockito.Mockito.spy;
2835

2936
public class UtilsVerifierTest {
3037

@@ -51,6 +58,35 @@ public void shouldFailOnInstanceFields() {
5158
.verify();
5259
}
5360

61+
@Test
62+
public void shouldFailOnInstanceMethod() {
63+
expectedException.expect(AssertionError.class);
64+
expectedException.expectMessage(containsString("instanceMethod"));
65+
66+
suppressedVerifier(InstanceMethods.class)
67+
.suppressInstanceMethodCheck(false)
68+
.verify();
69+
}
70+
71+
@Test
72+
public void shouldFailWhenNoConstructor() {
73+
expectedException.expect(AssertionError.class);
74+
75+
suppressedVerifier(DefaultConstructor.class)
76+
.suppressPrivateConstructorCheck(false)
77+
.verify();
78+
}
79+
80+
@Test
81+
public void shouldFailWhenNoPrivateConstructor() {
82+
expectedException.expect(AssertionError.class);
83+
expectedException.expectMessage(containsString("should be private"));
84+
85+
suppressedVerifier(NonPrivateConstructor.class)
86+
.suppressPrivateConstructorCheck(false)
87+
.verify();
88+
}
89+
5490
@Test
5591
public void shouldFailOnMultipleConstructors() {
5692
expectedException.expect(AssertionError.class);
@@ -95,11 +131,27 @@ public void shouldPassForWellFormedUtil() {
95131
UtilsVerifier.forClass(WellFormed.class).verify();
96132
}
97133

134+
@Test
135+
public void shouldThrowIllegalStateExceptionOnInstantiationReflectionProblems() {
136+
expectedException.expect(IllegalStateException.class);
137+
138+
suppressedVerifier(AbstractClass.class).verify();
139+
}
140+
141+
@Test
142+
public void shouldFailOnClassWithNoConstructor() {
143+
expectedException.expect(AssertionError.class);
144+
expectedException.expectMessage(containsString("has no constructor"));
145+
146+
suppressedVerifier(Runnable.class).verify();
147+
}
148+
98149
private static <T> UtilsVerifier<T> suppressedVerifier(final Class<T> type) {
99150
return UtilsVerifier.forClass(type)
100151
.suppressFinalClassCheck(true)
101152
.suppressOnlyOneConstructorCheck(true)
102153
.suppressPrivateConstructorCheck(true)
103-
.suppressInstanceFieldCheck(true);
154+
.suppressInstanceFieldCheck(true)
155+
.suppressInstanceMethodCheck(true);
104156
}
105157
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/**
2+
* Copyright (c) 2017-present, UtilsVerifier Contributors.
3+
* <p>
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in
5+
* compliance with the License. You may obtain a copy of the License at
6+
* <p>
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
* <p>
9+
* Unless required by applicable law or agreed to in writing, software distributed under the License is
10+
* distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See
11+
* the License for the specific language governing permissions and limitations under the License.
12+
*/
13+
package com.github.karczews.utilsverifier.subjects;
14+
15+
public abstract class AbstractClass {
16+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/**
2+
* Copyright (c) 2017-present, UtilsVerifier Contributors.
3+
* <p>
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in
5+
* compliance with the License. You may obtain a copy of the License at
6+
* <p>
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
* <p>
9+
* Unless required by applicable law or agreed to in writing, software distributed under the License is
10+
* distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See
11+
* the License for the specific language governing permissions and limitations under the License.
12+
*/
13+
package com.github.karczews.utilsverifier.subjects;
14+
15+
public final class DefaultConstructor {
16+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* Copyright (c) 2017-present, UtilsVerifier Contributors.
3+
* <p>
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in
5+
* compliance with the License. You may obtain a copy of the License at
6+
* <p>
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
* <p>
9+
* Unless required by applicable law or agreed to in writing, software distributed under the License is
10+
* distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See
11+
* the License for the specific language governing permissions and limitations under the License.
12+
*/
13+
package com.github.karczews.utilsverifier.subjects;
14+
15+
public final class InstanceMethods {
16+
17+
private void instanceMethod() {
18+
}
19+
20+
private InstanceMethods() {
21+
}
22+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/**
2+
* Copyright (c) 2017-present, UtilsVerifier Contributors.
3+
* <p>
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in
5+
* compliance with the License. You may obtain a copy of the License at
6+
* <p>
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
* <p>
9+
* Unless required by applicable law or agreed to in writing, software distributed under the License is
10+
* distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See
11+
* the License for the specific language governing permissions and limitations under the License.
12+
*/
13+
package com.github.karczews.utilsverifier.subjects;
14+
15+
public final class NonPrivateConstructor {
16+
public NonPrivateConstructor() {
17+
}
18+
}

0 commit comments

Comments
 (0)