我开始在我的项目中使用 JUnit 和 Mockito,我很快注意到我最终将我的私有方法转换为公共方法以便从测试类中访问,这是一个糟糕的解决方案。
有时只测试公共方法就足够了,但有时我也想真正测试一些内部方法。有解决方法吗?例如,允许 JUnit 将私有方法模拟为公共或类似的特殊注释?
我开始在我的项目中使用 JUnit 和 Mockito,我很快注意到我最终将我的私有方法转换为公共方法以便从测试类中访问,这是一个糟糕的解决方案。
有时只测试公共方法就足够了,但有时我也想真正测试一些内部方法。有解决方法吗?例如,允许 JUnit 将私有方法模拟为公共或类似的特殊注释?
需要直接测试私有方法是一种设计味道。在一个设计良好的类中,所有功能都可以通过其公共接口访问、合理并因此可以测试。
缺少这个通常意味着你的类太大太复杂,试图同时处理多个职责。最好的解决方案是重构:将一些功能提取到一个单独的类中,在那里它可以公开可用,因此可以直接进行单元测试。
您的公共方法必须调用您的私有方法。因此,您可以通过创建公共方法的测试功能来测试您的私有方法。
如果你还想通过 Junits 测试私有函数,你可以使用 reflection
.
您必须设置方法的属性setAccessible==true.
例子:
public void testisvalid() throws Exception
{
MyHandler handler = new MyHandler();
Method privateStringMethod = MyHandler.class.getDeclaredMethod("isvalid", Long.class);
privateStringMethod.setAccessible(true);
String = (String) privateStringMethod.invoke(handler, 852l );
assertNotNull(s);
}
在中,getDeclaredMethod
您必须按顺序给出方法的名称private
,以及arguments
您在函数中传递的类型。
要问的第一个问题是:这些私有方法是否可以成为附加帮助类的公共接口的一部分。在这种情况下,您可以测试这个助手类,并在原始类中注入一个模拟助手。
如果不可能,则使这些私有方法受到保护,记录它们受保护的事实只是为了进行测试,并且不应被子类调用或覆盖,并将测试类与该类放在同一个包中正在测试能够访问这个受保护的方法。
在这种情况下,我使用@VisibleForTesting
Guava 提供的注释。
我的 Maven 构建基础架构为测试源提供了一个单独的目录,但具有相同的包结构。因此,如果方法不是公共的但可以通过包访问就足够了。