许多私有方法的Java测试类

10

我有一个类,它的职责是将合同从CSV文件导入数据库。

这个类本身只有一个公共方法来启动导入过程,其他方法都是私有的(因为只有该类本身会使用,并且它们包含逻辑)。

我开始使用 Spock 对这个类进行测试,但其中有许多私有方法,应该如何测试呢?

我应该将它们变成公共方法进行测试吗?只测试主要方法,即公共方法?

什么是最好的选择?


1
你可以将那些私有方法转换为包级别的方法(而不是公共方法),然后你的测试只需要在同一个包中即可。 - Gus
1
我建议阅读这个Stack Overflow帖子:https://dev59.com/9HVD5IYBdhLWcg3wDXF3 - Bohuslav Burghardt
2
Spock测试用例是用Groovy编写的,这意味着它们可以调用私有的(Java)方法。所以这不是一个技术问题,而只是一个关于您是否想要去那里的问题。 - Peter Niederwieser
@Ascalonian,这将会破坏封装性。 - Kennedy Oliveira
@PeterNiederwieser 不知道这件事。 - Kennedy Oliveira
显示剩余3条评论
4个回答

16

理论上,您的私有方法最终被其中一个公共方法使用,否则它们根本没有被使用。因此,通常您设置测试以使用必要的上下文调用公共方法,使其触及您的私有方法。

单元测试主要测试编译单元(即类)。您可以直接对方法进行单元测试,但是这样它们必须是公共的,这与拥有良好清晰的API相矛盾。

因此,请测试公共方法以足够的方式触及所有私有方法。私有方法是类的内部机制,不需要直接测试。


谢谢,我会这样测试! - Kennedy Oliveira

5
您可以使用反射来实现此操作。Method类有一个名为setAccessible(boolean)的方法,它使您能够调用即使声明为private / protected / default也可以调用。请参见下面的示例:
YourClass yourClassInstance = new YourClass();
Method yourMethod = YourClass.class.getDeclaredMethod("yourMethod", null);
yourMethod.setAccessible(true);
Object[] parameters = new Object[1];
parameters[0] = "A String parameter";
Object result = yourMethod.invoke(yourClassInstance, parameters);

2

有些人认为你只应该测试API(即公共方法)。

一种可能的解决方案是使用包私有性,这样只有在同一个包中的类才能访问那些方法。

个人而言,我不会测试私有方法,而是会专注于公共方法是否按预期执行。如果你觉得你的私有方法负担过重,那么它们可能确实如此,你应该进一步分离功能。


0
如果您的类实现了一个接口,您可以将想要测试的所有方法设置为“public”,但不要将它们添加到接口中。在这种情况下,您将能够从测试中访问这些方法,但无法从您的源代码中访问它们。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接