Skip to content

Commit

Permalink
Merge pull request #19751 from famod/testinfo-before-after
Browse files Browse the repository at this point in the history
Fix wrong TestInfo test method in @Before/AfterEach
  • Loading branch information
gsmet authored Aug 30, 2021
2 parents d6a20dc + 5db60de commit 76bccdb
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.reflect.Method;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
Expand All @@ -22,11 +27,29 @@
@QuarkusTest
public class QuarkusTestCallbacksTestCase {

@BeforeEach
void beforeEachWithTestInfo(TestInfo testInfo) throws NoSuchMethodException {
checkBeforeOrAfterEachTestInfo(testInfo, "beforeEachWithTestInfo");
}

@AfterEach
void afterEachWithTestInfo(TestInfo testInfo) throws NoSuchMethodException {
checkBeforeOrAfterEachTestInfo(testInfo, "afterEachWithTestInfo");
}

private void checkBeforeOrAfterEachTestInfo(TestInfo testInfo, String unexpectedMethodName) throws NoSuchMethodException {
assertNotNull(testInfo);
String testMethodName = testInfo.getTestMethod().get().getName();
assertNotEquals(testMethodName,
QuarkusTestCallbacksTestCase.class.getDeclaredMethod(unexpectedMethodName, TestInfo.class));
assertTrue(testMethodName.startsWith("test"));
}

@Test
@TestAnnotation
@Order(1)
public void testTestMethodHasAnnotation() {

assertTrue(SimpleAnnotationCheckerBeforeEachCallback.testAnnotationChecked);
}

@Test
Expand All @@ -36,11 +59,13 @@ public void testBeforeClass() {
}

@Test
@TestAnnotation
@Order(3)
public void testInfoTestCase(TestInfo testInfo) throws NoSuchMethodException {
Assertions.assertEquals(testInfo.getTestClass().get(), QuarkusTestCallbacksTestCase.class);
Assertions.assertEquals(testInfo.getTestMethod().get(),
QuarkusTestCallbacksTestCase.class.getDeclaredMethod("testInfoTestCase", TestInfo.class));
assertEquals(testInfo.getTestClass().get(), QuarkusTestCallbacksTestCase.class);
Method testMethod = testInfo.getTestMethod().get();
assertEquals(testMethod, QuarkusTestCallbacksTestCase.class.getDeclaredMethod("testInfoTestCase", TestInfo.class));
assertEquals(1, testMethod.getAnnotationsByType(TestAnnotation.class).length);
}

@Target({ METHOD })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

public class SimpleAnnotationCheckerBeforeEachCallback implements QuarkusTestBeforeEachCallback {

static boolean testAnnotationChecked;

@Override
public void beforeEach(QuarkusTestMethodContext context) {
// make sure that this comes into play only for the test we care about
Expand All @@ -26,5 +28,6 @@ public void beforeEach(QuarkusTestMethodContext context) {
throw new IllegalStateException(
"Expected to find annotation @TestAnnotation on method test method testTestMethodHasAnnotation");
}
testAnnotationChecked = true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.util.ArrayList;
import java.util.Deque;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
Expand Down Expand Up @@ -196,6 +197,8 @@ public void run() {
}
};

private final IdentityHashMap<Method, Method> tcclMethodCache = new IdentityHashMap<>();

static {
ClassLoader classLoader = QuarkusTestExtension.class.getClassLoader();
if (classLoader instanceof QuarkusClassLoader) {
Expand Down Expand Up @@ -430,6 +433,7 @@ public void close() throws IOException {
}
tm.close();
} finally {
tcclMethodCache.clear();
GroovyCacheCleaner.clearGroovyCache();
if (hangTaskKey != null) {
hangTaskKey.cancel(true);
Expand Down Expand Up @@ -988,13 +992,13 @@ private Object runExtensionMethod(ReflectiveInvocationContext<Method> invocation
try {
Class<?> testClassFromTCCL = Class.forName(extensionContext.getRequiredTestClass().getName(), true,
Thread.currentThread().getContextClassLoader());
Method newMethod = determineTCCLExtensionMethod(invocationContext, testClassFromTCCL);
Method newMethod = determineTCCLExtensionMethod(invocationContext.getExecutable(), testClassFromTCCL);
boolean methodFromEnclosing = false;
// this is needed to support before*** and after*** methods that are part of class that encloses the test class
// (the test class is in this case a @Nested test)
if ((newMethod == null) && (testClassFromTCCL.getEnclosingClass() != null)) {
testClassFromTCCL = testClassFromTCCL.getEnclosingClass();
newMethod = determineTCCLExtensionMethod(invocationContext, testClassFromTCCL);
newMethod = determineTCCLExtensionMethod(invocationContext.getExecutable(), testClassFromTCCL);
methodFromEnclosing = true;
}
if (newMethod == null) {
Expand Down Expand Up @@ -1035,8 +1039,9 @@ private Object runExtensionMethod(ReflectiveInvocationContext<Method> invocation
cloneRequired = false;
} else if (TestInfo.class.isAssignableFrom(theclass)) {
TestInfo info = (TestInfo) arg;
Method newTestMethod = determineTCCLExtensionMethod(info.getTestMethod().get(), testClassFromTCCL);
replacement = new TestInfoImpl(info.getDisplayName(), info.getTags(), Optional.of(testClassFromTCCL),
Optional.of(newMethod));
Optional.of(newTestMethod));
} else if (clonePattern.matcher(className).matches()) {
cloneRequired = true;
} else {
Expand Down Expand Up @@ -1089,13 +1094,16 @@ private Object runExtensionMethod(ReflectiveInvocationContext<Method> invocation
}
}

private Method determineTCCLExtensionMethod(ReflectiveInvocationContext<Method> invocationContext, Class<?> c)
private Method determineTCCLExtensionMethod(Method originalMethod, Class<?> c)
throws ClassNotFoundException {
Method newMethod = null;
Method newMethod = tcclMethodCache.get(originalMethod);
if (newMethod != null) {
return newMethod;
}
while (c != Object.class) {
if (c.getName().equals(invocationContext.getExecutable().getDeclaringClass().getName())) {
if (c.getName().equals(originalMethod.getDeclaringClass().getName())) {
try {
Class<?>[] originalParameterTypes = invocationContext.getExecutable().getParameterTypes();
Class<?>[] originalParameterTypes = originalMethod.getParameterTypes();
List<Class<?>> parameterTypesFromTccl = new ArrayList<>(originalParameterTypes.length);
for (Class<?> type : originalParameterTypes) {
if (type.isPrimitive()) {
Expand All @@ -1106,7 +1114,7 @@ private Method determineTCCLExtensionMethod(ReflectiveInvocationContext<Method>
Thread.currentThread().getContextClassLoader()));
}
}
newMethod = c.getDeclaredMethod(invocationContext.getExecutable().getName(),
newMethod = c.getDeclaredMethod(originalMethod.getName(),
parameterTypesFromTccl.toArray(new Class[0]));
break;
} catch (NoSuchMethodException ignored) {
Expand All @@ -1115,6 +1123,7 @@ private Method determineTCCLExtensionMethod(ReflectiveInvocationContext<Method>
}
c = c.getSuperclass();
}
tcclMethodCache.put(originalMethod, newMethod);
return newMethod;
}

Expand Down

0 comments on commit 76bccdb

Please sign in to comment.