Skip to content

Commit 4479e51

Browse files
authored
Merge pull request #14 from grimsa/bugfix/12
[JUnit5] support package-private test methods + minor refactoring
2 parents 445e291 + 8f2a7a8 commit 4479e51

File tree

2 files changed

+49
-50
lines changed

2 files changed

+49
-50
lines changed

src/main/java/io/github/jsonSnapshot/SnapshotMatcher.java

Lines changed: 40 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@
2020
import java.lang.reflect.Method;
2121
import java.util.ArrayList;
2222
import java.util.List;
23+
import java.util.Optional;
2324
import java.util.Set;
2425
import java.util.function.Function;
2526
import java.util.stream.Collectors;
27+
import java.util.stream.Stream;
2628

2729
public class SnapshotMatcher {
2830

@@ -80,19 +82,15 @@ public static void validateSnapshots() {
8082
public static Snapshot expect(Object firstObject, Object... others) {
8183

8284
if (clazz == null) {
83-
throw new SnapshotMatchException("SnapshotTester not yet started! Start it on @BeforeClass with SnapshotMatcher.start()");
84-
}
85-
try {
86-
Object[] objects = mergeObjects(firstObject, others);
87-
StackTraceElement stackElement = findStackElement();
88-
Method method = getMethod(stackElement, clazz);
89-
Snapshot snapshot = new Snapshot(snapshotFile, clazz, method, jsonFunction, objects);
90-
validateExpectCall(snapshot);
91-
calledSnapshots.add(snapshot);
92-
return snapshot;
93-
} catch (ClassNotFoundException e) {
94-
throw new SnapshotMatchException(e.getMessage());
85+
throw new SnapshotMatchException("SnapshotTester not yet started! Start it on @BeforeClass/@BeforeAll with SnapshotMatcher.start()");
9586
}
87+
Object[] objects = mergeObjects(firstObject, others);
88+
StackTraceElement stackElement = findStackElement();
89+
Method method = getMethod(clazz, stackElement.getMethodName());
90+
Snapshot snapshot = new Snapshot(snapshotFile, clazz, method, jsonFunction, objects);
91+
validateExpectCall(snapshot);
92+
calledSnapshots.add(snapshot);
93+
return snapshot;
9694
}
9795

9896
static Function<Object, String> defaultJsonFunction() {
@@ -144,46 +142,39 @@ private static void validateExpectCall(Snapshot snapshot) {
144142
}
145143
}
146144

147-
private static Method getMethod(StackTraceElement testClass, Class clazz) {
148-
Method method;
145+
private static Method getMethod(Class<?> clazz, String methodName) {
149146
try {
150-
method = clazz.getMethod(testClass.getMethodName());
147+
return clazz.getDeclaredMethod(methodName);
151148
} catch (NoSuchMethodException e) {
152-
throw new SnapshotMatchException("Please annotate your test method with @Test and make it without any parameters!");
149+
return Optional.ofNullable(clazz.getSuperclass())
150+
.map(superclass -> getMethod(superclass, methodName))
151+
.orElseThrow(() -> new SnapshotMatchException("Could not find method " + methodName + " on class " + clazz
152+
+ "\nPlease annotate your test method with @Test and make it without any parameters!"));
153153
}
154-
return method;
155154
}
156155

157-
private static StackTraceElement findStackElement() throws ClassNotFoundException {
156+
private static StackTraceElement findStackElement() {
158157
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
159-
160-
int i = 1; // Start after stackTrace
161-
while (i < stackTraceElements.length &&
162-
SnapshotMatcher.class.equals(Class.forName(stackTraceElements[i].getClassName()))) { //TODO
163-
i++;
158+
int elementsToSkip = 1; // Start after stackTrace
159+
while (SnapshotMatcher.class.getName().equals(stackTraceElements[elementsToSkip].getClassName())) {
160+
elementsToSkip++;
164161
}
165162

166-
for (int j = i; j < stackTraceElements.length; j++) {
167-
168-
try {
169-
Class clazz = Class.forName(stackTraceElements[j].getClassName());
170-
Method method = clazz.getMethod(stackTraceElements[j].getMethodName());
171-
172-
// Navigate into stack until Test class/method level
173-
if (method.isAnnotationPresent(Test.class) || method.isAnnotationPresent(BeforeClass.class) ||
174-
method.isAnnotationPresent(org.junit.jupiter.api.Test.class) || method.isAnnotationPresent(BeforeAll.class)) {
175-
i = j;
176-
break;
177-
}
178-
}
179-
catch(NoSuchMethodException ignored) {
180-
181-
}
182-
}
163+
return Stream.of(stackTraceElements)
164+
.skip(elementsToSkip)
165+
.filter(stackTraceElement -> hasTestAnnotation(getMethod(getClass(stackTraceElement.getClassName()), stackTraceElement.getMethodName())))
166+
.findFirst()
167+
.orElseThrow(() -> new SnapshotMatchException("Could not locate a method with one of supported test annotations"));
168+
}
183169

184-
return stackTraceElements[i];
170+
private static boolean hasTestAnnotation(Method method) {
171+
return method.isAnnotationPresent(Test.class)
172+
|| method.isAnnotationPresent(BeforeClass.class)
173+
|| method.isAnnotationPresent(org.junit.jupiter.api.Test.class)
174+
|| method.isAnnotationPresent(BeforeAll.class);
185175
}
186176

177+
187178
private static Object[] mergeObjects(Object firstObject, Object[] others) {
188179
Object[] objects = new Object[1];
189180
objects[0] = firstObject;
@@ -192,4 +183,12 @@ private static Object[] mergeObjects(Object firstObject, Object[] others) {
192183
}
193184
return objects;
194185
}
186+
187+
private static Class<?> getClass(String className) {
188+
try {
189+
return Class.forName(className);
190+
} catch (ClassNotFoundException e) {
191+
throw new IllegalArgumentException(e);
192+
}
193+
}
195194
}

src/test/java/io/github/jsonSnapshot/SnapshotIntegrationTest.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,37 +13,37 @@
1313
public class SnapshotIntegrationTest {
1414

1515
@BeforeAll
16-
public static void beforeAll() {
16+
static void beforeAll() {
1717
start();
1818
}
1919

2020
@AfterAll
21-
public static void afterAll() {
21+
static void afterAll() {
2222
validateSnapshots();
2323
}
2424

2525
@Test
26-
public void shouldMatchSnapshotOne() {
26+
void shouldMatchSnapshotOne() {
2727
expect(FakeObject.builder().id("anyId1").value(1).name("anyName1").build()).toMatchSnapshot();
2828
}
2929

3030
@Test
31-
public void shouldMatchSnapshotTwo() {
31+
void shouldMatchSnapshotTwo() {
3232
expect(FakeObject.builder().id("anyId2").value(2).name("anyName2").build()).toMatchSnapshot();
3333
}
3434

3535
@Test
36-
public void shouldMatchSnapshotThree() {
36+
void shouldMatchSnapshotThree() {
3737
expect(FakeObject.builder().id("anyId3").value(3).name("anyName3").build()).toMatchSnapshot();
3838
}
3939

4040
@Test
41-
public void shouldMatchSnapshotFour() {
41+
void shouldMatchSnapshotFour() {
4242
expect(FakeObject.builder().id("anyId4").value(4).name("any\n\n\nName4").build()).toMatchSnapshot();
4343
}
4444

4545
@Test
46-
public void shouldMatchSnapshotInsidePrivateMethod() {
46+
void shouldMatchSnapshotInsidePrivateMethod() {
4747
matchInsidePrivate();
4848
}
4949

@@ -52,13 +52,13 @@ private void matchInsidePrivate() {
5252
}
5353

5454
@Test
55-
public void shouldThrowSnapshotMatchException() {
55+
void shouldThrowSnapshotMatchException() {
5656
assertThrows(SnapshotMatchException.class, expect(FakeObject.builder().id("anyId5").value(6).name("anyName5").build())::toMatchSnapshot, "Error on: \n" +
5757
"io.github.jsonSnapshot.SnapshotIntegrationTest.shouldThrowSnapshotMatchException=[");
5858
}
5959

6060
@Test
61-
public void shouldThrowStackOverflowError() {
61+
void shouldThrowStackOverflowError() {
6262
// Create cycle JSON
6363
FakeObject fakeObject1 = FakeObject.builder().id("anyId1").value(1).name("anyName1").build();
6464
FakeObject fakeObject2 = FakeObject.builder().id("anyId2").value(2).name("anyName2").build();

0 commit comments

Comments
 (0)