mirror of
https://github.com/alibaba/testable-mock.git
synced 2025-03-10 01:30:29 +08:00
allow modify static final field
This commit is contained in:
parent
93ad1fa94f
commit
a78931ae81
@ -20,6 +20,7 @@
|
||||
| mock.target.checking.enable | 是否启用Mock目标有效性的前置检查 | 可用值为:`true` / `false`,当前默认值为`false` |
|
||||
| omni.constructor.enhance.enable | 是否启用`OmniConstructor`的字节码增强模式 | 可用值为:`true` / `false` |
|
||||
| omni.constructor.enhance.pkgPrefix.excludes | 对特定包禁用`OmniConstructor`的字节码增强模式 | 使用`,`分隔的包路径前缀列表,例如:`com.demo.model` |
|
||||
| private.access.enhance.enable | 是否启用`PrivateAccessor`的字节码增强模式 | 可用值为:`true` / `false` |
|
||||
| thread.pool.enhance.enable | 是否启用基于`TransmittableThreadLocal`的Mock上下文存储 | 可用值为:`true` / `false` |
|
||||
|
||||
参见`demo`目录各示例项目中的`testable.properties`文件。
|
||||
|
@ -28,6 +28,7 @@ public class PropertiesParser {
|
||||
private static final String DEFAULT_MOCK_SCOPE = "mock.scope.default";
|
||||
private static final String ENABLE_MOCK_TARGET_CHECK = "mock.target.checking.enable";
|
||||
private static final String ENABLE_OMNI_INJECT = "omni.constructor.enhance.enable";
|
||||
private static final String ENABLE_FINAL_INJECT = "private.access.enhance.enable";
|
||||
private static final String ENABLE_THREAD_POOL = "thread.pool.enhance.enable";
|
||||
|
||||
public static void parseFile(String configFilePath) {
|
||||
@ -75,6 +76,8 @@ public class PropertiesParser {
|
||||
GlobalConfig.enhanceOmniConstructor = Boolean.parseBoolean(v);
|
||||
} else if (k.equals(ENABLE_MOCK_INJECT)) {
|
||||
GlobalConfig.enhanceMock = Boolean.parseBoolean(v);
|
||||
} else if (k.equals(ENABLE_FINAL_INJECT)) {
|
||||
GlobalConfig.enhanceFinal = Boolean.parseBoolean(v);
|
||||
} else if (k.equals(ENABLE_MOCK_TARGET_CHECK)) {
|
||||
GlobalConfig.checkMockTargetExistence = Boolean.parseBoolean(v);
|
||||
} else if (k.equals(ENABLE_THREAD_POOL)) {
|
||||
|
@ -0,0 +1,20 @@
|
||||
package com.alibaba.testable.agent.handler;
|
||||
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.FieldNode;
|
||||
|
||||
/**
|
||||
* @author flin
|
||||
*/
|
||||
public class FinalFieldClassHandler extends BaseClassHandler {
|
||||
|
||||
@Override
|
||||
protected void transform(ClassNode cn) {
|
||||
if ((cn.access & ACC_INTERFACE) == 0) {
|
||||
for (FieldNode field : cn.fields) {
|
||||
field.access &= ~ACC_FINAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,10 +1,7 @@
|
||||
package com.alibaba.testable.agent.transformer;
|
||||
|
||||
import com.alibaba.testable.agent.constant.ConstPool;
|
||||
import com.alibaba.testable.agent.handler.MockClassHandler;
|
||||
import com.alibaba.testable.agent.handler.OmniClassHandler;
|
||||
import com.alibaba.testable.agent.handler.SourceClassHandler;
|
||||
import com.alibaba.testable.agent.handler.TestClassHandler;
|
||||
import com.alibaba.testable.agent.handler.*;
|
||||
import com.alibaba.testable.agent.handler.test.Framework;
|
||||
import com.alibaba.testable.agent.model.MethodInfo;
|
||||
import com.alibaba.testable.agent.util.*;
|
||||
@ -55,6 +52,7 @@ public class TestableClassTransformer implements ClassFileTransformer {
|
||||
}
|
||||
byte[] bytes = GlobalConfig.enhanceOmniConstructor ?
|
||||
new OmniClassHandler().getBytes(classFileBuffer) : classFileBuffer;
|
||||
bytes = GlobalConfig.enhanceFinal ? new FinalFieldClassHandler().getBytes(bytes) : bytes;
|
||||
if (GlobalConfig.enhanceMock) {
|
||||
ClassNode cn = ClassUtil.getClassNode(className);
|
||||
if (cn != null) {
|
||||
|
@ -35,6 +35,7 @@ public class GlobalConfig {
|
||||
private static String[] pkgPrefixBlackList = null;
|
||||
private static Map<String, String> mockPkgMapping = null;
|
||||
public static MockScope defaultMockScope = MockScope.GLOBAL;
|
||||
public static boolean enhanceFinal = false;
|
||||
public static boolean enhanceMock = true;
|
||||
public static boolean enhanceOmniConstructor = false;
|
||||
public static boolean enhanceThreadLocal = false;
|
||||
|
@ -226,7 +226,7 @@ public class OmniConstructor {
|
||||
}
|
||||
|
||||
private static Object createInstance(Class<?> clazz, Set<Class<?>> classPool)
|
||||
throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
|
||||
throws InstantiationException, IllegalAccessException, InvocationTargetException {
|
||||
Constructor<?> constructor = getBestConstructor(clazz);
|
||||
if (constructor == null) {
|
||||
throw new ClassConstructionException("Fail to invoke constructor of " + clazz.getName());
|
||||
|
Loading…
Reference in New Issue
Block a user