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

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


当前回答

测试私有方法的最佳方法是通过另一个公共方法。如果无法做到这一点,则以下条件之一为真:

私有方法是死代码您正在测试的类附近有设计气味您尝试测试的方法不应是私有的

其他回答

在过去,我曾为Java使用过反射,在我看来这是一个很大的错误。

严格来说,您不应该编写直接测试私有方法的单元测试。您应该测试的是类与其他对象的公共契约;您不应该直接测试对象的内部。如果另一个开发人员想要对类进行一个小的内部更改,这不会影响类的公共契约,那么他/她就必须修改基于反射的测试,以确保它正常工作。如果在整个项目中重复这样做,那么单元测试就不再是代码健康状况的有用度量,而开始成为开发的障碍,成为开发团队的烦恼。

相反,我建议使用一个代码覆盖工具,例如Cobertura,以确保您编写的单元测试在私有方法中提供代码的适当覆盖。通过这种方式,您可以间接测试私有方法正在做什么,并保持更高级别的灵活性。

我倾向于不测试私人方法。这里有疯狂。我个人认为,你应该只测试你公开的接口(包括受保护的和内部的方法)。

如果你担心没有像很多帖子所建议的那样测试私有方法,那么考虑一下代码覆盖工具将准确地确定你的代码被测试了多少以及泄漏的地方,所以这样做是可以接受的。

将问题作者引向“变通方法”的答案对社区造成了巨大的伤害。测试是所有工程学科的主要组成部分。你不会想买一辆没有经过适当测试的汽车,而且测试的方式很有意义,那么为什么有人会想购买或使用测试不好的软件呢?人们这样做的原因可能是因为测试不好的软件的影响是事后才感受到的,我们通常不会把它们与身体伤害联系起来。

这是一种非常危险的观念,很难改变,但我们有责任提供安全的产品,而不管管理层如何欺负我们。想想Equifax黑客。。。

我们必须努力营造一个鼓励良好软件工程实践的环境。这并不意味着排斥我们中那些不认真对待自己手艺的弱者/懒惰者,而是创造一种责任感和自我反思的现状,鼓励每个人在精神和技能上追求成长。

我仍在学习,可能自己也有错误的看法/观点,但我坚信,我们需要对良好做法负责,避免不负责任的黑客或解决问题的方法。

如果您有一些遗留的Java应用程序,并且不允许更改方法的可见性,那么测试私有方法的最佳方法是使用反射。

在内部,我们使用助手来获取/设置私有和私有静态变量,以及调用私有和私有的静态方法。以下模式将允许您执行与私有方法和字段相关的任何操作。当然,您不能通过反射来更改私有静态final变量。

Method method = TargetClass.getDeclaredMethod(methodName, argClasses);
method.setAccessible(true);
return method.invoke(targetObject, argObjects);

对于字段:

Field field = TargetClass.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(object, value);

笔记:TargetClass.getDeclaredMethod(methodName,argClasses)允许您查看私有方法。同样的事情也适用于getDeclaredField。需要setAccessible(true)才能与private一起玩。

在C++中:在包含包含要测试的私有函数的类头之前。

使用此代码:

#define private public
#define protected public