support nested annotation of junit 5

This commit is contained in:
金戟 2021-04-24 16:59:29 +08:00
parent be0a580a04
commit 9f5867ed76
3 changed files with 32 additions and 2 deletions

View File

@ -34,6 +34,7 @@ public class TestableClassTransformer implements ClassFileTransformer {
private static final String FIELD_VALUE = "value"; private static final String FIELD_VALUE = "value";
private static final String FIELD_TREAT_AS = "treatAs"; private static final String FIELD_TREAT_AS = "treatAs";
private static final String CLASS_JUNIT_5_NESTED = "Lorg/junit/jupiter/api/Nested;";
/** /**
* Just avoid spend time to scan those surely non-user classes, should keep these lists as tiny as possible * Just avoid spend time to scan those surely non-user classes, should keep these lists as tiny as possible
@ -119,7 +120,7 @@ public class TestableClassTransformer implements ClassFileTransformer {
} }
private String foundMockForTestClass(String className) { private String foundMockForTestClass(String className) {
ClassNode cn = ClassUtil.getClassNode(className); ClassNode cn = adaptInnerClass(ClassUtil.getClassNode(className));
if (cn != null) { if (cn != null) {
String mockClass = lookForMockWithAnnotationAsTestClass(cn); String mockClass = lookForMockWithAnnotationAsTestClass(cn);
if (mockClass != null) { if (mockClass != null) {
@ -133,6 +134,18 @@ public class TestableClassTransformer implements ClassFileTransformer {
return lookForOuterMockClass(className); return lookForOuterMockClass(className);
} }
private ClassNode adaptInnerClass(ClassNode cn) {
if (cn == null || cn.visibleAnnotations == null) {
return cn;
}
for (AnnotationNode an : cn.visibleAnnotations) {
if (an.desc.equals(CLASS_JUNIT_5_NESTED)) {
return ClassUtil.getClassNode(ClassUtil.toOuterClassName(cn.name));
}
}
return cn;
}
private String lookForOuterMockClass(String className) { private String lookForOuterMockClass(String className) {
String mockClassName = ClassUtil.getMockClassName(ClassUtil.getSourceClassName(className)); String mockClassName = ClassUtil.getMockClassName(ClassUtil.getSourceClassName(className));
if (mockClassParser.isMockClass(ClassUtil.getClassNode(mockClassName))) { if (mockClassParser.isMockClass(ClassUtil.getClassNode(mockClassName))) {

View File

@ -234,8 +234,17 @@ public class ClassUtil {
return cn; return cn;
} }
/**
* Get outer class name from a inner class name
* @param name inner class name
* @return outer class name
*/
public static String toOuterClassName(String name) {
int pos = name.lastIndexOf("$");
return (pos > 0) ? name.substring(0, pos) : name;
}
private static String toDescriptor(Byte type, String objectType) { private static String toDescriptor(Byte type, String objectType) {
return "(" + (char)type.byteValue() + ")L" + objectType + ";"; return "(" + (char)type.byteValue() + ")L" + objectType + ";";
} }
} }

View File

@ -23,5 +23,13 @@ class ClassUtilTest {
ClassUtil.fitCompanionClassName("com/alibaba/testable/demo/BlackBox$Companion")); ClassUtil.fitCompanionClassName("com/alibaba/testable/demo/BlackBox$Companion"));
} }
@Test
void should_get_outer_class_name() {
assertEquals("com/alibaba/demo/basic/DemoMockTest",
ClassUtil.toOuterClassName("com/alibaba/demo/basic/DemoMockTest$Inner"));
assertEquals("com/alibaba/demo/basic/DemoMockTest",
ClassUtil.toOuterClassName("com/alibaba/demo/basic/DemoMockTest"));
}
} }