如何对私有方法进行单元测试,私有方法属于私有静态类。
public class ProjectModel {
//some code
private static class MyStaticClass{
private model (Object obj, Map<String , Object> model)
}
}
我试图意识到它给了NoSuchMethodException
Method method = projectModel.getClass().getDeclaredMethod("model", methodParameters);
答案 0 :(得分:2)
假设您的课程ProjectModel
位于privateaccessor.tst
个包中,而您的非静态方法model
会返回int
。
package privateaccessor.tst;
public class ProjectModel {
//some code
private static class MyStaticClass{
private int model (Object obj, Map<String , Object> model) {
return 42;
}
}
}
然后在测试中,您可以使用反射来获取私有类“Class
”对象并创建实例。然后,您可以使用PrivateAccessor
(包含在Junit Addons中)来调用方法model()
。
@Test
public void testPrivate() throws Throwable {
final Class clazz = Class.forName("privateaccessor.tst.ProjectModel$MyStaticClass");
// Get the private constructor ...
final Constructor constructor = clazz.getDeclaredConstructor();
// ... and make it accessible.
constructor.setAccessible(true);
// Then create an instance of class MyStaticClass.
final Object instance = constructor.newInstance();
// Invoke method model(). The primitive int return value will be
// wrapped in an Integer.
final Integer result = (Integer) PrivateAccessor.invoke(instance, "model", new Class[]{Object.class, Map.class}, new Object[]{null, null});
assertEquals(42, result.intValue());
}
答案 1 :(得分:1)
您可以尝试使用此代码来解决异常:
Method method = projectModel.getClass().getDeclaredClasses()[0]
.getDeclaredMethod("model", methodParameters);
出于测试目的,您可以尝试以下代码来调用model
方法:
Class<?> innerClass = projectModel.getClass().getDeclaredClasses()[0];
Constructor<?> constructor = innerClass.getDeclaredConstructors()[0];
constructor.setAccessible(true);
Object mystaticClass = constructor.newInstance();
Method method = mystaticClass.getClass().getDeclaredMethod("model", new Class[]{Object.class,Map.class});
method.setAccessible(true);
method.invoke(mystaticClass, null, null);
答案 2 :(得分:0)
一般不建议对私有方法和类进行测试。如果您仍想测试一些非公共功能,我建议不要private
,而是package private
这样的方法和类,并将您的测试用例放在同一个包中(但要放在单独的源目录中)喜欢它通常在maven项目中完成。)
您可以使用
解决您的特定反思问题Class.forName(ProjectModel.class.getName()+"$MyStaticClass")
.getDeclaredMethod("model", methodParameters);
但我不建议使用这种方法,因为将来很难支持这样的测试用例。