support invoke private companion object method in kotlin

This commit is contained in:
金戟 2020-12-01 23:49:48 +08:00
parent 001001bfd3
commit 1d98e3c618
6 changed files with 56 additions and 35 deletions

View File

@ -18,22 +18,6 @@ public class DemoPrivateAccess {
*/ */
public final Double pi = 3.14; public final Double pi = 3.14;
/**
* method accessing private static field
*/
public static String privateStaticFieldAccessFunc() {
staticCount += 3;
return String.valueOf(staticCount);
}
/**
* method accessing private member field
*/
public String privateFieldAccessFunc() {
count += 2;
return String.valueOf(count);
}
/** /**
* private static method * private static method
*/ */

View File

@ -20,12 +20,10 @@ class DemoPrivateAccessTest {
@Test @Test
void should_able_to_access_private_field() throws Exception { void should_able_to_access_private_field() throws Exception {
demoPrivateAccess.count = 2; demoPrivateAccess.count = 2;
assertEquals("4", demoPrivateAccess.privateFieldAccessFunc()); assertEquals(new Integer(2), demoPrivateAccess.count);
assertEquals(new Integer(4), demoPrivateAccess.count);
PrivateAccessor.set(demoPrivateAccess, "count", 3); PrivateAccessor.set(demoPrivateAccess, "count", 3);
assertEquals("5", demoPrivateAccess.privateFieldAccessFunc()); assertEquals(new Integer(3), PrivateAccessor.get(demoPrivateAccess, "count"));
assertEquals(new Integer(5), PrivateAccessor.get(demoPrivateAccess, "count"));
} }
@Test @Test
@ -37,12 +35,10 @@ class DemoPrivateAccessTest {
@Test @Test
void should_able_to_access_private_static_field() throws Exception { void should_able_to_access_private_static_field() throws Exception {
//DemoPrivateAccess.staticCount = 2; //DemoPrivateAccess.staticCount = 2;
//assertEquals("5", DemoPrivateAccess.privateStaticFieldAccessFunc()); //assertEquals(new Integer(2), DemoPrivateAccess.staticCount);
//assertEquals(new Integer(5), DemoPrivateAccess.staticCount);
PrivateAccessor.setStatic(DemoPrivateAccess.class, "staticCount", 3); PrivateAccessor.setStatic(DemoPrivateAccess.class, "staticCount", 3);
assertEquals("6", DemoPrivateAccess.privateStaticFieldAccessFunc()); assertEquals(new Integer(3), PrivateAccessor.getStatic(DemoPrivateAccess.class, "staticCount"));
assertEquals(new Integer(6), PrivateAccessor.getStatic(DemoPrivateAccess.class, "staticCount"));
} }
@Test @Test

View File

@ -2,23 +2,43 @@ package com.alibaba.testable.demo
class DemoPrivateAccess { class DemoPrivateAccess {
/**
* a private member field
*/
private var count = 0 private var count = 0
final val pi = 3.14 /**
* a constant field
*/
val pi = 3.14
/** /**
* private method * private member method
*/ */
private fun privateFunc(s: String, i: Int): String { private fun privateFunc(s: String, i: Int): String {
return "$s - $i" return "$s - $i"
} }
companion object {
/** /**
* method with private field access * a private static field
*/ */
fun privateFieldAccessFunc(): String { private var staticCount = 0
count += 2
return count.toString() /**
* private static method
*/
private fun privateStaticFunc(s: String, i: Int): String {
return "$s + $i"
}
/**
* private jvm static method
*/
@JvmStatic private fun privateJvmStaticFunc(s: String, i: Int): String {
return "$s * $i"
}
} }
} }

View File

@ -17,8 +17,19 @@ internal class DemoPrivateAccessTest {
@Test @Test
fun should_able_to_access_private_field() { fun should_able_to_access_private_field() {
PrivateAccessor.set(demoPrivateAccess, "count", 3) PrivateAccessor.set(demoPrivateAccess, "count", 3)
assertEquals("5", demoPrivateAccess.privateFieldAccessFunc()) assertEquals(3, PrivateAccessor.get(demoPrivateAccess, "count"))
assertEquals(5, PrivateAccessor.get(demoPrivateAccess, "count")) }
@Test
fun should_able_to_access_private_static_method() {
assertEquals("hello + 1", PrivateAccessor.invokeStatic(DemoPrivateAccess::class.java, "privateStaticFunc", "hello", 1))
assertEquals("hello * 1", PrivateAccessor.invokeStatic(DemoPrivateAccess::class.java, "privateJvmStaticFunc", "hello", 1))
}
@Test
fun should_able_to_access_private_static_field() {
PrivateAccessor.setStatic(DemoPrivateAccess::class.java, "staticCount", 3)
assertEquals(3, PrivateAccessor.getStatic(DemoPrivateAccess::class.java, "staticCount"))
} }
@Test @Test

View File

@ -10,6 +10,8 @@ import java.lang.reflect.Method;
*/ */
public class PrivateAccessor { public class PrivateAccessor {
private static final String KOTLIN_COMPANION_FIELD = "Companion";
public static <T> T get(Object ref, String field) { public static <T> T get(Object ref, String field) {
try { try {
Field declaredField = ref.getClass().getDeclaredField(field); Field declaredField = ref.getClass().getDeclaredField(field);
@ -75,6 +77,15 @@ public class PrivateAccessor {
declaredMethod.setAccessible(true); declaredMethod.setAccessible(true);
return (T)declaredMethod.invoke(null, args); return (T)declaredMethod.invoke(null, args);
} }
// fit kotlin companion object, will throw 'NoSuchFieldException' otherwise
Field companionClassField = clazz.getDeclaredField(KOTLIN_COMPANION_FIELD);
declaredMethod = TypeUtil.getMethodByNameAndParameterTypes(
companionClassField.getType().getDeclaredMethods(), method, cls);
Object companionInstance = getStatic(clazz, KOTLIN_COMPANION_FIELD);
if (declaredMethod != null && companionInstance != null) {
declaredMethod.setAccessible(true);
return (T)declaredMethod.invoke(companionInstance, args);
}
} catch (Exception e) { } catch (Exception e) {
System.err.println("Failed to invoke private static method \"" + method + "\": " + e.toString()); System.err.println("Failed to invoke private static method \"" + method + "\": " + e.toString());
return null; return null;

View File

@ -67,7 +67,6 @@ public class TestableUtil {
} }
} }
} }
System.err.println("testCaseName: " + testCaseName);
return testCaseName; return testCaseName;
} }