標籤:
在Java開發階段,因為追求架構規範和遵循設計原則,所以要用private和protected修飾符去定義類的成員方法、變數、常量,這使得代碼具封裝性、內聚性等,但在測試階段會造成一定的不便。通過Java的反射機制,便能很好地解決該問題。
ReflectUtil.java
//....../** * @author yumin * @since 2015-03-02 14:52 */public class ReflectUtil { private ReflectUtil() { } //部份代碼略 public static Object invokeMethod(Object object, String methodName, Class[] parameterTypes, Object[] args) { Object result = null; if (null != object) { try { Method method = getDeclaredMethod(object, methodName, parameterTypes); result = method.invoke(object, args); } catch (NoSuchMethodException e) { //...... } catch (IllegalAccessException e) { //...... } catch (InvocationTargetException e) { //...... } } return result; } public static Method getDeclaredMethod(Object object, String methodName, Class[] parameterTypes) throws NoSuchMethodException { Method method = null; if (null != object) { method = object.getClass().getDeclaredMethod(methodName, parameterTypes); method.setAccessible(true); } return method; }}
ReflectUtilTest.java
//....../** * @author yumin * @since 2015-03-02 14:53 */public class ReflectUtilTest { //部份代碼略 @Test public void testInvokeMethod() throws Exception { String whatIsYourName = null; String howOldAreYou = null; String name = "yumin"; int age = 18; Person person = new Person(); whatIsYourName = (String) ReflectUtil.invokeMethod(person, "whatIsYourName", null, null); howOldAreYou = (String) ReflectUtil.invokeMethod(person, "howOldAreYou", new Class[]{int.class}, new Object[]{age}); Assert.assertEquals(Person.whatIsYourName + name, whatIsYourName); Assert.assertEquals(Person.howOldAreYou + age, howOldAreYou); } public class Person { public static final String whatIsYourName = "My name is "; public static final String howOldAreYou = "I‘m "; private String name = "yumin"; // 姓名 public void setName(String name) { this.name = name; } private String whatIsYourName() { return whatIsYourName + name; } private String howOldAreYou(int age) { return howOldAreYou + age; } }}
可以看到通過Java反射機制,實現了對被private和protected所修飾方法和屬性的調用、取值、傳值等讀寫操作,未破壞原始代碼也能完成對私人成員的單元測試。需要特別注意的是,建議僅運用在測試情境,切莫圖方便在生產環境發行的代碼邏輯中也通過反射調用類私人成員,這樣便破壞原有的類設計,產生不可預料的結果及汙染體繫結構造成後續難以維護。
更詳細代碼請參見:https://github.com/wangym/java-common/
通過Java反射測試類別私人成員