Android JUnitTests——是否有可能为方法和场反射创建一个公共静态方法?



我知道如何从Test class内的Class访问private methodfield:

访问MyClass的私有方法,命名为void doSomething():

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
...
try {
    Method method = MyClass.class.getDeclaredMethod("doSomething", (Class[])null); // (Class[])null is for parameterless methods
    method.setAccessible(true);
    method.invoke(localInstanceOfMyClass);
}
catch (NoSuchMethodException ex){
    ex.printStackTrace();
}
catch (IllegalAccessException ex){
    ex.printStackTrace();
}
catch (IllegalArgumentException ex){
    ex.printStackTrace();
}
catch (InvocationTargetException ex) {
    ex.printStackTrace();
}

访问MyClass的私有字段,命名为boolean myField:

import java.lang.reflect.Field;
...
try {
    Field field = MyClass.class.getDeclaredField("myField");
    field.setAccessible(true);
    field.set(localInstanceOfMyClass, true); // true is the value I want to assign to myField
}
catch (NoSuchFieldException ex){
    ex.printStackTrace();
}
catch (IllegalAccessException ex){
    ex.printStackTrace();
}
catch (IllegalArgumentException ex){
    ex.printStackTrace();
}

(来源:https://stackoverflow.com/a/34658/1682559)

你可以看到,这是相当多的代码,只是把private boolean放在truefalse


所以,我的问题:是否有可能以某种方式使两个public static methods,两个用于Method,一个用于Field,我可以在所有Test Classes中使用?澄清:

TestMethodsClass.setPrivateField(... some parameters ...);
TestMethodsClass.runPrivateVoidMethod(... some parameters ...);
TestMethodsClass.runPrivateReturnMethod(... some parameters ...);

根据上面void doSomething() en boolean myField示例的参数举例:

TestMethodsClass.setPrivateField(localInstanceOfMyClass, "myField", true);
TestMethodsClass.runPrivateVoidMethod(localInstanceOfMyClass, "doSomething", null);
// PS: null will be converted in the method itself to (Class[])null`

提前感谢您的回复。

好吧,这其实很简单。

TestMethodsClass:

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class TestMethodsClass
{
    public static void runPrivateVoidMethod(Object ob, String methodName, Class<?>[] parameters){
        try {
            Method method = null;
            if(parameters == null){
                Class<?>[] nullParameter = (Class[])null;
                method = ob.getClass().getDeclaredMethod(methodName, nullParameter);
            }
            else
                method = ob.getClass().getDeclaredMethod(methodName, parameters);
            if(method != null){
                method.setAccessible(true);
                method.invoke(ob);
            }
        }
        catch (NoSuchMethodException ex){
            ex.printStackTrace();
        }
        catch (IllegalAccessException ex){
            ex.printStackTrace();
        }
        catch (IllegalArgumentException ex){
            ex.printStackTrace();
        }
        catch (InvocationTargetException ex) {
            ex.printStackTrace();
        }
    }
    public static Object runPrivateReturnMethod(Object ob, String methodName, Class<?>[] parameters){
        Object returnObject = null;
        try {
            if(parameters == null){
                Class<?>[] nullParameter = (Class[])null;
                Method method = ob.getClass().getDeclaredMethod(methodName, nullParameter);
                method.setAccessible(true);
                returnObject = method.invoke(ob);
            }
            else{
                Method method = ob.getClass().getDeclaredMethod(methodName, parameters);
                method.setAccessible(true);
                method.invoke(ob);
            }
        }
        catch (NoSuchMethodException ex){
            ex.printStackTrace();
        }
        catch (IllegalAccessException ex){
            ex.printStackTrace();
        }
        catch (IllegalArgumentException ex){
            ex.printStackTrace();
        }
        catch (InvocationTargetException ex) {
            ex.printStackTrace();
        }
        return returnObject;
    }
    public static void setPrivateField(Object ob, String fieldName, Object value){
        try {
            Field field = ob.getClass().getDeclaredField(fieldName);
            field.setAccessible(true);
            field.set(ob, value);
        }
        catch (NoSuchFieldException ex){
            ex.printStackTrace();
        }
        catch (IllegalAccessException ex){
            ex.printStackTrace();
        }
        catch (IllegalArgumentException ex){
            ex.printStackTrace();
        }
    }
}

如何命名:

// Set private field "boolean myField" from MyClass to true
TestMethodsClass.setPrivateField(localInstanceOfMyClass, "myField", true);
// Run private method "doSomething()" from MyClass
TestMethodsClass.runPrivateVoidMethod(localInstanceOfMyClass, "doSomething", null);
// Run private method "doSomething()" from MyClass and assign the return value to a local field
boolean test = (boolean)TestMethodsClass.runPrivateReturnMethod(localInstanceOfMyClass, "doSomething", null);

我还没有完全测试过,所以我不知道它是否适用于所有类型。但据我所知,字符串和布尔值工作得很好。我会做更多的测试,当我有一些空闲时间从我的项目。

相关内容

  • 没有找到相关文章

最新更新