mirror of
https://github.com/alibaba/testable-mock.git
synced 2025-02-13 13:20:32 +08:00
fix bytecode order and async test case
This commit is contained in:
parent
2fda70d7b4
commit
26712108d6
@ -83,10 +83,11 @@ public class TestClassHandler extends BaseClassHandler {
|
||||
private AbstractInsnNode[] replaceTestableUtilField(MethodNode mn, AbstractInsnNode[] instructions,
|
||||
String fieldName, int pos) {
|
||||
InsnList insnNodes = new InsnList();
|
||||
insnNodes.insert(new VarInsnNode(ALOAD, 0));
|
||||
// NOTE: will insert in reversed order
|
||||
insnNodes.insert(new MethodInsnNode(INVOKESTATIC, CLASS_TESTABLE_UTIL, FIELD_TO_METHOD_MAPPING.get(fieldName),
|
||||
SIGNATURE_TESTABLE_UTIL_METHOD, false));
|
||||
mn.instructions.insertBefore(instructions[pos], insnNodes);
|
||||
insnNodes.insert(new VarInsnNode(ALOAD, 0));
|
||||
mn.instructions.insert(instructions[pos], insnNodes);
|
||||
mn.instructions.remove(instructions[pos]);
|
||||
return mn.instructions.toArray();
|
||||
}
|
||||
|
@ -5,7 +5,14 @@ package com.alibaba.testable.core.tool;
|
||||
*/
|
||||
public class TestableTool {
|
||||
|
||||
/**
|
||||
* Name of current test case method
|
||||
*/
|
||||
public static String TEST_CASE;
|
||||
|
||||
/**
|
||||
* Name of the last visited method in source class
|
||||
*/
|
||||
public static String SOURCE_METHOD;
|
||||
|
||||
}
|
||||
|
@ -7,6 +7,10 @@ import java.io.*;
|
||||
*/
|
||||
public class ResourceUtil {
|
||||
|
||||
/**
|
||||
* Read content of a text file from resource folder
|
||||
* @param filePath file to read
|
||||
*/
|
||||
public static String fetchText(String filePath) {
|
||||
InputStream in = ResourceUtil.class.getResourceAsStream("/" + filePath);
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
|
||||
@ -24,6 +28,10 @@ public class ResourceUtil {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read content of a binary file from resource folder
|
||||
* @param filePath file to read
|
||||
*/
|
||||
public static byte[] fetchBinary(String filePath) {
|
||||
InputStream in = ResourceUtil.class.getResourceAsStream("/" + filePath);
|
||||
if (in == null) {
|
||||
|
@ -7,6 +7,11 @@ import java.util.List;
|
||||
*/
|
||||
public class StringUtil {
|
||||
|
||||
/**
|
||||
* Join strings
|
||||
* @param list strings to join
|
||||
* @param conjunction connection character
|
||||
*/
|
||||
static public String join(List<String> list, String conjunction)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
@ -7,19 +7,27 @@ import com.alibaba.testable.core.constant.ConstPool;
|
||||
*/
|
||||
public class TestableUtil {
|
||||
|
||||
/**
|
||||
* Get the last visit method in source file
|
||||
* @param testClassRef usually `this` variable of the test class
|
||||
* @return method name
|
||||
*/
|
||||
public static String currentSourceMethodName(Object testClassRef) {
|
||||
Class<?> testClass = testClassRef.getClass();
|
||||
StackTraceElement[] stack = getMainThread().getStackTrace();
|
||||
String testClassName = getRealClassName(testClass);
|
||||
String sourceClassName = testClassName.substring(0, testClassName.length() - ConstPool.TEST_POSTFIX.length());
|
||||
for (int i = stack.length - 1; i >= 0; i--) {
|
||||
if (stack[i].getClassName().equals(sourceClassName)) {
|
||||
return stack[i].getMethodName();
|
||||
}
|
||||
String sourceMethod = findLastMethodFromSourceClass(sourceClassName, getMainThread().getStackTrace());
|
||||
if (sourceMethod.isEmpty()) {
|
||||
return findLastMethodFromSourceClass(sourceClassName, Thread.currentThread().getStackTrace());
|
||||
}
|
||||
return "";
|
||||
return sourceMethod;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current test case method
|
||||
* @param testClassRef usually `this` variable of the test class
|
||||
* @return method name
|
||||
*/
|
||||
public static String currentTestCaseName(Object testClassRef) {
|
||||
Class<?> testClass = testClassRef.getClass();
|
||||
StackTraceElement[] stack = getMainThread().getStackTrace();
|
||||
@ -32,6 +40,15 @@ public class TestableUtil {
|
||||
return "";
|
||||
}
|
||||
|
||||
private static String findLastMethodFromSourceClass(String sourceClassName, StackTraceElement[] stack) {
|
||||
for (StackTraceElement element : stack) {
|
||||
if (element.getClassName().equals(sourceClassName)) {
|
||||
return element.getMethodName();
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private static String getRealClassName(Class<?> testClass) {
|
||||
String className = testClass.getName();
|
||||
int posOfInnerClass = className.lastIndexOf('$');
|
||||
@ -44,6 +61,7 @@ public class TestableUtil {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
// usually impossible to go here
|
||||
return Thread.currentThread();
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ import com.alibaba.testable.core.annotation.TestableInject;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import static com.alibaba.testable.core.tool.TestableTool.SOURCE_METHOD;
|
||||
import static com.alibaba.testable.core.tool.TestableTool.TEST_CASE;
|
||||
@ -41,6 +42,9 @@ class DemoServiceTest {
|
||||
|
||||
@TestableInject
|
||||
private String callFromDifferentMethod() {
|
||||
if (TEST_CASE.equals("should_able_to_get_test_case_name")) {
|
||||
return "mock_special";
|
||||
}
|
||||
switch (SOURCE_METHOD) {
|
||||
case "callerOne": return "mock_one";
|
||||
default: return "mock_others";
|
||||
@ -81,15 +85,19 @@ class DemoServiceTest {
|
||||
|
||||
@Test
|
||||
void should_able_to_get_source_method_name() throws Exception {
|
||||
assertEquals("mock_one_mock_others", demoService.callerTwo() + "_" + demoService.callerOne());
|
||||
assertEquals("mock_one_mock_others", ((Callable<String>)() ->
|
||||
demoService.callerOne() + "_" + demoService.callerTwo()).call());
|
||||
// synchronous
|
||||
assertEquals("mock_one_mock_others", demoService.callerOne() + "_" + demoService.callerTwo());
|
||||
// asynchronous
|
||||
assertEquals("mock_one_mock_others",
|
||||
Executors.newSingleThreadExecutor().submit(() -> demoService.callerOne() + "_" + demoService.callerTwo()).get());
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_able_to_get_test_case_name() throws Exception {
|
||||
assertEquals("should_able_to_get_test_case_name", TEST_CASE);
|
||||
assertEquals("should_able_to_get_test_case_name", ((Callable<String>)() -> TEST_CASE).call());
|
||||
// synchronous
|
||||
assertEquals("mock_special", demoService.callerOne());
|
||||
// asynchronous
|
||||
assertEquals("mock_special", Executors.newSingleThreadExecutor().submit(() -> demoService.callerOne()).get());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import com.alibaba.testable.core.tool.TestableTool.SOURCE_METHOD
|
||||
import com.alibaba.testable.core.tool.TestableTool.TEST_CASE
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.util.concurrent.Callable
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
|
||||
@EnableTestable
|
||||
@ -29,9 +29,15 @@ internal class DemoServiceTest {
|
||||
private fun startsWith(self: BlackBox, s: String) = false
|
||||
|
||||
@TestableInject
|
||||
private fun callFromDifferentMethod() = when (SOURCE_METHOD) {
|
||||
"callerOne" -> "mock_one"
|
||||
else -> "mock_others"
|
||||
private fun callFromDifferentMethod(): String {
|
||||
return if (TEST_CASE == "should_able_to_get_test_case_name") {
|
||||
"mock_special"
|
||||
} else {
|
||||
when (SOURCE_METHOD) {
|
||||
"callerOne" -> "mock_one"
|
||||
else -> "mock_others"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val demoService = DemoService()
|
||||
@ -65,15 +71,21 @@ internal class DemoServiceTest {
|
||||
|
||||
@Test
|
||||
fun should_able_to_get_source_method_name() {
|
||||
assertEquals("mock_one_mock_others", demoService.callerTwo() + "_" + demoService.callerOne())
|
||||
assertEquals("mock_one_mock_others", Callable<String> {
|
||||
// synchronous
|
||||
assertEquals("mock_one_mock_others", demoService.callerOne() + "_" + demoService.callerTwo())
|
||||
// asynchronous
|
||||
assertEquals("mock_one_mock_others", Executors.newSingleThreadExecutor().submit<String> {
|
||||
demoService.callerOne() + "_" + demoService.callerTwo()
|
||||
}.call())
|
||||
}.get())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun should_able_to_get_test_case_name() {
|
||||
assertEquals("should_able_to_get_test_case_name", TEST_CASE)
|
||||
assertEquals("should_able_to_get_test_case_name", Callable<String> { TEST_CASE }.call())
|
||||
// synchronous
|
||||
assertEquals("mock_special", demoService.callerOne())
|
||||
// asynchronous
|
||||
assertEquals("mock_special", Executors.newSingleThreadExecutor().submit<String> {
|
||||
demoService.callerOne()
|
||||
}.get())
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user