mirror of
https://github.com/alibaba/testable-mock.git
synced 2025-01-09 20:00:21 +08:00
use mock context to store invocation record
This commit is contained in:
parent
9a22f361f3
commit
374a4d5442
@ -13,16 +13,20 @@ import java.lang.instrument.Instrumentation;
|
||||
public class PreMain {
|
||||
|
||||
private static final String AND = "&";
|
||||
private static final String USE_THREAD_POOL = "useThreadPool";
|
||||
private static final String LOG_LEVEL = "logLevel";
|
||||
private static final String DUMP_PATH = "dumpPath";
|
||||
private static final String PKG_PREFIX = "pkgPrefix";
|
||||
private static final String EQUAL = "=";
|
||||
private static boolean enhanceThreadLocal = false;
|
||||
|
||||
public static void premain(String agentArgs, Instrumentation inst) {
|
||||
// add transmittable thread local transformer
|
||||
TtlAgent.premain(agentArgs, inst);
|
||||
// add testable mock transformer
|
||||
parseArgs(agentArgs);
|
||||
if (enhanceThreadLocal) {
|
||||
// add transmittable thread local transformer
|
||||
TtlAgent.premain(agentArgs, inst);
|
||||
}
|
||||
// add testable mock transformer
|
||||
inst.addTransformer(new TestableClassTransformer());
|
||||
}
|
||||
|
||||
@ -33,6 +37,7 @@ public class PreMain {
|
||||
for (String a : args.split(AND)) {
|
||||
int i = a.indexOf(EQUAL);
|
||||
if (i > 0) {
|
||||
// parameter with key = value
|
||||
String k = a.substring(0, i);
|
||||
String v = a.substring(i + 1);
|
||||
if (k.equals(LOG_LEVEL)) {
|
||||
@ -43,7 +48,10 @@ public class PreMain {
|
||||
GlobalConfig.setPkgPrefix(v);
|
||||
}
|
||||
} else {
|
||||
GlobalConfig.setLogLevel(a);
|
||||
// parameter with single value
|
||||
if (a.equals(USE_THREAD_POOL)) {
|
||||
enhanceThreadLocal = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,8 +4,6 @@ import com.alibaba.testable.agent.constant.ConstPool;
|
||||
import com.alibaba.testable.agent.tool.ImmutablePair;
|
||||
import com.alibaba.testable.agent.util.AnnotationUtil;
|
||||
import com.alibaba.testable.agent.util.ClassUtil;
|
||||
import com.alibaba.testable.core.util.InvokeRecordUtil;
|
||||
import com.alibaba.testable.core.util.TestableUtil;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.tree.*;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
package com.alibaba.testable.agent.model;
|
||||
|
||||
import com.alibaba.testable.agent.tool.UnnullableMap;
|
||||
import com.alibaba.testable.core.util.UnnullableMap;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
@ -2,7 +2,6 @@ package com.alibaba.testable.core.matcher;
|
||||
|
||||
import com.alibaba.testable.core.error.VerifyFailedError;
|
||||
import com.alibaba.testable.core.model.Verification;
|
||||
import com.alibaba.testable.core.util.InvokeRecordUtil;
|
||||
import com.alibaba.testable.core.util.MockContextUtil;
|
||||
import com.alibaba.testable.core.util.TestableUtil;
|
||||
|
||||
@ -27,10 +26,7 @@ public class InvokeVerifier {
|
||||
* @return the verifier object
|
||||
*/
|
||||
public static InvokeVerifier verify(String mockMethodName) {
|
||||
String testClass = MockContextUtil.context.get().testClassName;
|
||||
String testCaseName = MockContextUtil.context.get().testCaseName;
|
||||
String recordIdentify = InvokeRecordUtil.getInvokeIdentify(mockMethodName, testClass, testCaseName);
|
||||
return new InvokeVerifier(InvokeRecordUtil.getInvokeRecord(recordIdentify));
|
||||
return new InvokeVerifier(MockContextUtil.invokeRecord().get(mockMethodName));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,6 +1,10 @@
|
||||
package com.alibaba.testable.core.model;
|
||||
|
||||
import com.alibaba.testable.core.util.UnnullableMap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class MockContext {
|
||||
@ -11,9 +15,12 @@ public class MockContext {
|
||||
|
||||
public final Map<String, Object> parameters;
|
||||
|
||||
public final Map<String, List<Object[]>> invokeRecord;
|
||||
|
||||
public MockContext(String testClassName, String testCaseName) {
|
||||
this.testClassName = testClassName;
|
||||
this.testCaseName = testCaseName;
|
||||
this.parameters = new HashMap<String, Object>();
|
||||
this.invokeRecord = UnnullableMap.of(new ArrayList<Object[]>());
|
||||
}
|
||||
}
|
||||
|
@ -1,21 +1,10 @@
|
||||
package com.alibaba.testable.core.util;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author flin
|
||||
*/
|
||||
public class InvokeRecordUtil {
|
||||
|
||||
/**
|
||||
* Mock method name → List of invoke parameters
|
||||
*/
|
||||
private static final Map<String, List<Object[]>> INVOKE_RECORDS = new HashMap<String, List<Object[]>>();
|
||||
private final static String JOINER = "::";
|
||||
|
||||
/**
|
||||
* [0]Thread → [1]TestableUtil/TestableTool → [2]TestClass
|
||||
*/
|
||||
@ -32,37 +21,13 @@ public class InvokeRecordUtil {
|
||||
String mockMethodName = mockMethodTraceElement.getMethodName();
|
||||
String testClass = MockContextUtil.context.get().testClassName;
|
||||
String testCaseName = MockContextUtil.context.get().testCaseName;
|
||||
String identify = getInvokeIdentify(mockMethodName, testClass, testCaseName);
|
||||
List<Object[]> records = getInvokeRecord(identify);
|
||||
if (isConstructor) {
|
||||
records.add(args);
|
||||
LogUtil.verbose(" Mock constructor invoked \"%s\"", identify);
|
||||
MockContextUtil.invokeRecord().get(mockMethodName).add(args);
|
||||
LogUtil.verbose(" Mock constructor \"%s\" invoked in %s::%s", mockMethodName, testClass, testCaseName);
|
||||
} else {
|
||||
records.add(isTargetClassInParameter ? slice(args, 1) : args);
|
||||
LogUtil.verbose(" Mock method invoked \"%s\"", identify);
|
||||
MockContextUtil.invokeRecord().get(mockMethodName).add(isTargetClassInParameter ? slice(args, 1) : args);
|
||||
LogUtil.verbose(" Mock method \"%s\" invoked in %s::%s\"", mockMethodName, testClass, testCaseName);
|
||||
}
|
||||
INVOKE_RECORDS.put(identify, records);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get identify key for mock invocation record
|
||||
* @param mockMethodName mock method name
|
||||
* @param testClass test class name
|
||||
* @param testCaseName test case name
|
||||
* @return identify key
|
||||
*/
|
||||
public static String getInvokeIdentify(String mockMethodName, String testClass, String testCaseName) {
|
||||
return testClass + JOINER + testCaseName + JOINER + mockMethodName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mock method invoke count
|
||||
* @param identify key of invocation record
|
||||
* @return parameters used when specified method invoked in specified test case
|
||||
*/
|
||||
public static List<Object[]> getInvokeRecord(String identify) {
|
||||
List<Object[]> records = INVOKE_RECORDS.get(identify);
|
||||
return (records == null) ? new LinkedList<Object[]>() : records;
|
||||
}
|
||||
|
||||
private static Object[] slice(Object[] args, int firstIndex) {
|
||||
|
@ -3,9 +3,12 @@ package com.alibaba.testable.core.util;
|
||||
import com.alibaba.testable.core.model.MockContext;
|
||||
import com.alibaba.ttl.TransmittableThreadLocal;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class MockContextUtil {
|
||||
|
||||
public static TransmittableThreadLocal<MockContext> context = new TransmittableThreadLocal<MockContext>();
|
||||
public static InheritableThreadLocal<MockContext> context = new TransmittableThreadLocal<MockContext>();
|
||||
|
||||
/**
|
||||
* Should be invoked at the beginning of each test case method
|
||||
@ -21,8 +24,11 @@ public class MockContextUtil {
|
||||
context.remove();
|
||||
}
|
||||
|
||||
public static String testCaseMark() {
|
||||
MockContext context = MockContextUtil.context.get();
|
||||
return context.testClassName + "::" + context.testCaseName;
|
||||
public static Map<String, Object> parameters() {
|
||||
return MockContextUtil.context.get().parameters;
|
||||
}
|
||||
|
||||
public static Map<String, List<Object[]>> invokeRecord() {
|
||||
return MockContextUtil.context.get().invokeRecord;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.alibaba.testable.agent.tool;
|
||||
package com.alibaba.testable.core.util;
|
||||
|
||||
import com.alibaba.testable.core.accessor.PrivateAccessor;
|
||||
|
||||
@ -15,7 +15,7 @@ public class UnnullableMap<K, V> extends HashMap<K, V> {
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
public static <K, V> UnnullableMap<K, V> of(V defaultValue) {
|
||||
public static <K, V, T extends V> UnnullableMap<K, V> of(T defaultValue) {
|
||||
return new UnnullableMap<K, V>(defaultValue);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user