如何测试私有静态的私有方法 class
How to test private method of a private static class
我如何对私有静态方法中的私有方法进行单元测试 class。
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);
一般测试私有方法,类不推荐。如果您仍想测试一些非 public 功能,我建议使用此类方法 类 而不是 private
,而是 package private
并将您的测试用例放在相同的包(但像通常在 maven 项目中那样进入单独的源目录)。
您的特定反射问题可以使用
解决
Class.forName(ProjectModel.class.getName()+"$MyStaticClass")
.getDeclaredMethod("model", methodParameters);
但我不建议使用这种方法,因为将来很难支持这种测试用例。
您可以尝试此代码来解决异常:
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);
假设您的 class ProjectModel
在包 privateaccessor.tst
中并且您的非静态方法 model
returns 和 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' 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());
}
我如何对私有静态方法中的私有方法进行单元测试 class。
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);
一般测试私有方法,类不推荐。如果您仍想测试一些非 public 功能,我建议使用此类方法 类 而不是 private
,而是 package private
并将您的测试用例放在相同的包(但像通常在 maven 项目中那样进入单独的源目录)。
您的特定反射问题可以使用
解决Class.forName(ProjectModel.class.getName()+"$MyStaticClass")
.getDeclaredMethod("model", methodParameters);
但我不建议使用这种方法,因为将来很难支持这种测试用例。
您可以尝试此代码来解决异常:
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);
假设您的 class ProjectModel
在包 privateaccessor.tst
中并且您的非静态方法 model
returns 和 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' 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());
}