如何测试私有静态类的私有方法

时间:2015-05-13 08:36:41

标签: java junit

如何对私有方法进行单元测试,私有方法属于私有静态类。

 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);

3 个答案:

答案 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);

但我不建议使用这种方法,因为将来很难支持这样的测试用例。