mirror of
https://github.com/alibaba/testable-mock.git
synced 2025-03-14 03:40:25 +08:00
suggest use MockDiagnose to set log level
This commit is contained in:
parent
9eb8682ec0
commit
be53ea2d9c
@ -17,6 +17,7 @@ public class ConstPool {
|
||||
public static final String FIELD_TARGET_CLASS = "targetClass";
|
||||
|
||||
public static final String MOCK_WITH = "com.alibaba.testable.core.annotation.MockWith";
|
||||
public static final String MOCK_DIAGNOSE = "com.alibaba.testable.core.annotation.MockDiagnose";
|
||||
public static final String MOCK_METHOD = "com.alibaba.testable.core.annotation.MockMethod";
|
||||
public static final String MOCK_CONSTRUCTOR = "com.alibaba.testable.core.annotation.MockConstructor";
|
||||
|
||||
|
@ -11,7 +11,7 @@ import com.alibaba.testable.agent.util.ClassUtil;
|
||||
import com.alibaba.testable.agent.util.GlobalConfig;
|
||||
import com.alibaba.testable.agent.util.StringUtil;
|
||||
import com.alibaba.testable.core.model.ClassType;
|
||||
import com.alibaba.testable.core.model.MockDiagnose;
|
||||
import com.alibaba.testable.core.model.LogLevel;
|
||||
import com.alibaba.testable.core.util.LogUtil;
|
||||
import com.alibaba.testable.core.util.MockContextUtil;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
@ -48,12 +48,11 @@ public class TestableClassTransformer implements ClassFileTransformer {
|
||||
private static final String CLASS_OBJECT = "java/lang/Object";
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
private final String[] WHITELIST_PREFIXES = new String[] { "com/alibaba/testable/demo/" };
|
||||
private final String[] BLACKLIST_PREFIXES = new String[] { "jdk/", "java/", "javax/", "com/sun/",
|
||||
"org/apache/maven/", "com/alibaba/testable/", "junit/", "org/junit/", "org/testng/" };
|
||||
private final String[] WHITELIST_PREFIXES = new String[] {"com/alibaba/testable/demo/"};
|
||||
private final String[] BLACKLIST_PREFIXES = new String[] {"jdk/", "java/", "javax/", "com/sun/",
|
||||
"org/apache/maven/", "com/alibaba/testable/", "junit/", "org/junit/", "org/testng/"};
|
||||
|
||||
@Override
|
||||
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
|
||||
@ -103,7 +102,8 @@ public class TestableClassTransformer implements ClassFileTransformer {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
String dumpFile = StringUtil.joinPath(dumpDir, className.replace(SLASH, DOT).replace(DOLLAR, UNDERLINE) + ".class");
|
||||
String dumpFile = StringUtil.joinPath(dumpDir,
|
||||
className.replace(SLASH, DOT).replace(DOLLAR, UNDERLINE) + ".class");
|
||||
LogUtil.verbose("Dump class: " + dumpFile);
|
||||
FileOutputStream stream = new FileOutputStream(dumpFile);
|
||||
stream.write(bytes);
|
||||
@ -241,6 +241,7 @@ public class TestableClassTransformer implements ClassFileTransformer {
|
||||
|
||||
/**
|
||||
* Read @MockWith annotation upon class to fetch mock class
|
||||
*
|
||||
* @param className class that need to explore
|
||||
* @return name of mock class, null for not found
|
||||
*/
|
||||
@ -254,6 +255,7 @@ public class TestableClassTransformer implements ClassFileTransformer {
|
||||
|
||||
/**
|
||||
* Read @MockWith annotation upon class and inner class "Mock" to fetch mock class
|
||||
*
|
||||
* @param className class that need to explore
|
||||
* @return name of mock class, null for not found
|
||||
*/
|
||||
@ -283,14 +285,15 @@ public class TestableClassTransformer implements ClassFileTransformer {
|
||||
|
||||
/**
|
||||
* Get mock class from @MockWith annotation
|
||||
*
|
||||
* @param cn class that may have @MockWith annotation
|
||||
* @return mock class name
|
||||
*/
|
||||
private String parseMockWithAnnotation(ClassNode cn, ClassType expectedType) {
|
||||
if (cn.visibleAnnotations != null) {
|
||||
for (AnnotationNode an : cn.visibleAnnotations) {
|
||||
setupDiagnose(an);
|
||||
if (toDotSeparateFullClassName(an.desc).equals(ConstPool.MOCK_WITH)) {
|
||||
setupDiagnose(an);
|
||||
ClassType type = AnnotationUtil.getAnnotationParameter(an, FIELD_TREAT_AS, ClassType.GuessByName,
|
||||
ClassType.class);
|
||||
if (isExpectedType(cn.name, type, expectedType)) {
|
||||
@ -316,6 +319,7 @@ public class TestableClassTransformer implements ClassFileTransformer {
|
||||
|
||||
/**
|
||||
* Check whether any method in specified class has mock-related annotation
|
||||
*
|
||||
* @param className class that need to explore
|
||||
* @return found annotation or not
|
||||
*/
|
||||
@ -324,6 +328,7 @@ public class TestableClassTransformer implements ClassFileTransformer {
|
||||
if (cn == null) {
|
||||
return false;
|
||||
}
|
||||
setupDiagnose(cn);
|
||||
for (MethodNode mn : cn.methods) {
|
||||
if (mn.visibleAnnotations != null) {
|
||||
for (AnnotationNode an : mn.visibleAnnotations) {
|
||||
@ -352,11 +357,29 @@ public class TestableClassTransformer implements ClassFileTransformer {
|
||||
return cn;
|
||||
}
|
||||
|
||||
private void setupDiagnose(ClassNode cn) {
|
||||
if (cn.visibleAnnotations == null) {
|
||||
return;
|
||||
}
|
||||
for (AnnotationNode an : cn.visibleAnnotations) {
|
||||
setupDiagnose(an);
|
||||
}
|
||||
}
|
||||
|
||||
private void setupDiagnose(AnnotationNode an) {
|
||||
MockDiagnose diagnose = AnnotationUtil.getAnnotationParameter(an, FIELD_DIAGNOSE, null, MockDiagnose.class);
|
||||
if (diagnose != null) {
|
||||
LogUtil.setLevel(diagnose == MockDiagnose.ENABLE ? LogUtil.LogLevel.LEVEL_DIAGNOSE :
|
||||
(diagnose == MockDiagnose.VERBOSE ? LogUtil.LogLevel.LEVEL_VERBOSE : LogUtil.LogLevel.LEVEL_MUTE));
|
||||
if (toDotSeparateFullClassName(an.desc).equals(MOCK_WITH)) {
|
||||
setupDianose(an, FIELD_DIAGNOSE);
|
||||
}
|
||||
if (toDotSeparateFullClassName(an.desc).equals(ConstPool.MOCK_DIAGNOSE)) {
|
||||
setupDianose(an, FIELD_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
private void setupDianose(AnnotationNode an, String fieldDiagnose) {
|
||||
LogLevel level = AnnotationUtil.getAnnotationParameter(an, fieldDiagnose, null, LogLevel.class);
|
||||
if (level != null) {
|
||||
LogUtil.setLevel(level == LogLevel.ENABLE ? LogUtil.LogLevel.LEVEL_DIAGNOSE :
|
||||
(level == LogLevel.VERBOSE ? LogUtil.LogLevel.LEVEL_VERBOSE : LogUtil.LogLevel.LEVEL_MUTE));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,23 @@
|
||||
package com.alibaba.testable.core.annotation;
|
||||
|
||||
import com.alibaba.testable.core.model.LogLevel;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* Set extra mock parameter to test class
|
||||
*
|
||||
* @author flin
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
@Documented
|
||||
public @interface MockDiagnose {
|
||||
|
||||
/**
|
||||
* switch of mock diagnose information of current test class
|
||||
* @return enable or disable
|
||||
*/
|
||||
LogLevel value() default LogLevel.DISABLE;
|
||||
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package com.alibaba.testable.core.annotation;
|
||||
|
||||
import com.alibaba.testable.core.model.ClassType;
|
||||
import com.alibaba.testable.core.model.MockDiagnose;
|
||||
import com.alibaba.testable.core.model.LogLevel;
|
||||
|
||||
import javax.lang.model.type.NullType;
|
||||
import java.lang.annotation.*;
|
||||
@ -30,8 +30,9 @@ public @interface MockWith {
|
||||
|
||||
/**
|
||||
* switch of mock diagnose information of current test class
|
||||
* @deprecated to be removed in v0.6, use @MockDiagnose annotation instead
|
||||
* @return enable or disable
|
||||
*/
|
||||
MockDiagnose diagnose() default MockDiagnose.DISABLE;
|
||||
LogLevel diagnose() default LogLevel.DISABLE;
|
||||
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ package com.alibaba.testable.core.model;
|
||||
* @author flin
|
||||
*/
|
||||
|
||||
public enum MockDiagnose {
|
||||
public enum LogLevel {
|
||||
|
||||
/**
|
||||
* Be quiet
|
Loading…
Reference in New Issue
Block a user