add static access methods to private accessor

This commit is contained in:
金戟 2020-11-30 22:57:37 +08:00
parent 1af6b8c8b6
commit 472f90e7e4
5 changed files with 75 additions and 12 deletions

View File

@ -5,23 +5,47 @@ package com.alibaba.testable.demo;
*/ */
public class DemoPrivateAccess { public class DemoPrivateAccess {
/**
* a private static field
*/
private static int staticCount;
/**
* a private member field
*/
private int count; private int count;
/**
* a constant field
*/
public final Double pi = 3.14; public final Double pi = 3.14;
/** /**
* private method * method accessing private static field
*/ */
private String privateFunc(String s, int i) { public static String privateStaticFieldAccessFunc() {
return s + " - " + i; staticCount += 3;
return String.valueOf(staticCount);
} }
/** /**
* method with private field access * method accessing private member field
*/ */
public String privateFieldAccessFunc() { public String privateFieldAccessFunc() {
count += 2; count += 2;
return String.valueOf(count); return String.valueOf(count);
} }
/**
* private static method
*/
private static String privateStaticFunc(String s, int i) {
return s + " + " + i;
}
/**
* private member method
*/
private String privateFunc(String s, int i) {
return s + " - " + i;
}
} }

View File

@ -28,6 +28,23 @@ class DemoPrivateAccessTest {
assertEquals(new Integer(5), PrivateAccessor.get(demoPrivateAccess, "count")); assertEquals(new Integer(5), PrivateAccessor.get(demoPrivateAccess, "count"));
} }
@Test
void should_able_to_access_private_static_method() throws Exception {
//assertEquals("hello + 1", DemoPrivateAccess.privateStaticFunc("hello", 1));
assertEquals("hello + 1", PrivateAccessor.invokeStatic(DemoPrivateAccess.class, "privateStaticFunc", "hello", 1));
}
@Test
void should_able_to_access_private_static_field() throws Exception {
//DemoPrivateAccess.staticCount = 2;
//assertEquals("5", DemoPrivateAccess.privateStaticFieldAccessFunc());
//assertEquals(new Integer(5), DemoPrivateAccess.staticCount);
PrivateAccessor.setStatic(DemoPrivateAccess.class, "staticCount", 3);
assertEquals("6", DemoPrivateAccess.privateStaticFieldAccessFunc());
assertEquals(new Integer(6), PrivateAccessor.getStatic(DemoPrivateAccess.class, "staticCount"));
}
@Test @Test
void should_able_to_update_final_field() throws Exception { void should_able_to_update_final_field() throws Exception {
demoPrivateAccess.pi = 4.13; demoPrivateAccess.pi = 4.13;

View File

@ -39,6 +39,7 @@ class Demo {
若要测试此方法可以利用TestableMock直接读取私有成员变量的值对结果进行校验 若要测试此方法可以利用TestableMock直接读取私有成员变量的值对结果进行校验
```java ```java
@EnablePrivateAccess // 启用TestableMock的私有成员访问功能
class DemoTest { class DemoTest {
private Demo demo = new Demo(); private Demo demo = new Demo();

View File

@ -16,7 +16,7 @@ public class PrivateAccessor {
declaredField.setAccessible(true); declaredField.setAccessible(true);
return (T)declaredField.get(ref); return (T)declaredField.get(ref);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); System.err.println("Failed to get private field \"" + field + "\": " + e.toString());
return null; return null;
} }
} }
@ -27,7 +27,7 @@ public class PrivateAccessor {
declaredField.setAccessible(true); declaredField.setAccessible(true);
declaredField.set(ref, value); declaredField.set(ref, value);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); System.err.println("Failed to set private field \"" + field + "\": " + e.toString());
} }
} }
@ -40,12 +40,33 @@ public class PrivateAccessor {
return (T)declaredMethod.invoke(ref, args); return (T)declaredMethod.invoke(ref, args);
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); System.err.println("Failed to invoke private method \"" + method + "\": " + e.toString());
return null; return null;
} }
return null; return null;
} }
public static <T> T getStatic(Class<?> clazz, String field) {
try {
Field declaredField = clazz.getDeclaredField(field);
declaredField.setAccessible(true);
return (T)declaredField.get(null);
} catch (Exception e) {
System.err.println("Failed to get private static field \"" + field + "\": " + e.toString());
return null;
}
}
public static <T> void setStatic(Class<?> clazz, String field, T value) {
try {
Field declaredField = clazz.getDeclaredField(field);
declaredField.setAccessible(true);
declaredField.set(null, value);
} catch (Exception e) {
System.err.println("Failed to set private static field \"" + field + "\": " + e.toString());
}
}
public static <T> T invokeStatic(Class<?> clazz, String method, Object... args) { public static <T> T invokeStatic(Class<?> clazz, String method, Object... args) {
try { try {
Class<?>[] cls = TypeUtil.getClassesFromObjects(args); Class<?>[] cls = TypeUtil.getClassesFromObjects(args);
@ -55,7 +76,7 @@ public class PrivateAccessor {
return (T)declaredMethod.invoke(null, args); return (T)declaredMethod.invoke(null, args);
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); System.err.println("Failed to invoke private static method \"" + method + "\": " + e.toString());
return null; return null;
} }
return null; return null;

View File

@ -14,10 +14,10 @@ class TestableUtilTest {
} }
@Test @Test
void should_get_async_method_name_from_inner_class_name() { void should_get_method_name_from_lambda_class_or_method() {
assertEquals("should_able_to_get_source_method_name", assertEquals("should_able_to_get_source_method_name",
PrivateAccessor.<String>invokeStatic(TestableUtil.class, "getAsyncMethodName", "com.alibaba.testable.demo.DemoMockTest$should_able_to_get_source_method_name$1")); PrivateAccessor.<String>invokeStatic(TestableUtil.class, "getMethodNameFromLambda", "com.alibaba.testable.demo.DemoMockTest$should_able_to_get_source_method_name$1"));
assertEquals("should_able_to_get_source_method_name", assertEquals("should_able_to_get_source_method_name",
PrivateAccessor.<String>invokeStatic(TestableUtil.class, "getAsyncMethodName", "lambda$should_able_to_get_source_method_name$0")); PrivateAccessor.<String>invokeStatic(TestableUtil.class, "getMethodNameFromLambda", "lambda$should_able_to_get_source_method_name$0"));
} }
} }