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

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


当前回答

对于Java,我会使用反射,因为我不喜欢仅仅为了测试而更改对声明方法的包的访问。然而,我通常只测试公共方法,这也应该确保私有方法正常工作。

不能使用反射从所有者类外部获取私有方法,私有修饰符也会影响反射

这不是真的。你当然可以,正如塞姆·卡提卡斯的回答中所提到的。

其他回答

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

使用此代码:

#define private public
#define protected public

正如其他人所说。。。不要直接测试私有方法。以下是一些想法:

保持所有方法的规模和重点(易于测试,易于发现错误)使用代码覆盖工具。我喜欢Cobertura(哦,快乐的一天,它看起来像是一个新版本!)

在单元测试上运行代码覆盖率。如果您发现方法没有经过充分测试,请添加到测试中以提高覆盖率。目标是100%的代码覆盖率,但要意识到你可能无法做到这一点。

如果您试图测试您不愿意或无法更改的现有代码,则反射是一个不错的选择。

如果类的设计仍然是灵活的,并且您有一个复杂的私有方法需要单独测试,我建议您将其导出到一个单独的类中,并单独测试该类。这不需要更改原始类的公共接口;它可以在内部创建helper类的实例并调用helper方法。

如果您想测试来自helper方法的困难错误条件,可以更进一步。从helper类中提取一个接口,向原始类中添加一个公共getter和setter以注入helper类(通过其接口使用),然后将helper类的模拟版本注入原始类中,以测试原始类如何响应helper的异常。如果您想测试原始类而不同时测试助手类,这种方法也很有用。

我和我的团队正在使用Typemock,它有一个API,允许您伪造非公共方法。

最近,他们增加了伪造不可见类型和使用xUnit的能力。

我不确定这是否是一种好的技术,但我开发了以下模式来单元测试私有方法:

我不修改要测试的方法的可见性,也不添加其他方法。相反,我为要测试的每个私有方法添加了一个额外的公共方法。我调用这个额外的方法TestPort,并用前缀t_表示它们。然后,此测试端口方法只需访问相应的私有方法。

此外,我向测试端口方法添加了一个布尔标志,以决定是否从外部通过测试端口方法授予对私有方法的访问权。然后在静态类中全局设置该标志,在该类中我放置了例如应用程序的其他全局设置。因此,我可以在一个地方打开和关闭对私有方法的访问,例如,在相应的单元测试中。