如何使用JUnit测试具有内部私有方法、字段或嵌套类的类?

仅仅为了能够运行测试而更改方法的访问修饰符似乎是不好的。


当前回答

测试私有方法会破坏类的封装,因为每次更改内部实现时都会破坏客户端代码(在本例中是测试)。

所以不要测试私有方法。

其他回答

您可以关闭反射的Java访问限制,这样私有就没有什么意义了。

setAccessible(true)调用实现了这一点。

唯一的限制是ClassLoader可能不允许您这样做。

有关在Java中实现这一点的方法,请参阅颠覆单元测试的Java访问保护(Ross Burton)。

正如上面许多人所建议的,一个好的方法是通过公共接口测试它们。

如果您这样做,最好使用代码覆盖工具(如EMMA)来查看您的私有方法是否确实在测试中执行。

如果您正在使用JUnit,请查看JUnit插件。它能够忽略Java安全模型并访问私有方法和属性。

如果使用Spring,ReflectionTestUtils提供了一些方便的工具,可以帮助您以最小的工作量完成任务。例如,要在私有成员上设置模拟,而不必强制添加不需要的公共setter:

ReflectionTestUtils.setField(theClass, "theUnsettableField", theMockObject);

在Spring Framework中,您可以使用以下方法测试私有方法:

ReflectionTestUtils.invokeMethod()

例如:

ReflectionTestUtils.invokeMethod(TestClazz, "createTest", "input data");