我正在尝试用一些私有方法对一个类进行单元测试。每个私有方法都可以相当广泛。
我可以使方法包作用域(导致警告),或者我可以使用下面的代码来测试它:
Method method = instance.getClass().getDeclaredMethod("methodName");
method.setAccessible(true);
Object object = method.invoke(instance);
assertNotNull(object);
这个班不是“上帝对象”,它的大多数方法都触及它的所有领域。
有关如何更好地处理此问题的任何建议吗?
答案 0 :(得分:11)
测试私有方法也可能是一种测试气味。
我的参考书是优秀的书http://www.manning.com/rainsberger/
你应该测试行为而不是方法:粒度有点不同。
示例1:要测试桩,如何在不引用彼此的情况下测试
push
和pop
?但是测试全球行为是可能的。这提醒我们,即使是测试,对象也是正确的粒度,而不是方法。示例2:当您想测试多个对象之间的交互时,按方法测试方法显然不正确,您想测试一个全局行为。
如果某个方法不公开,则外部世界无法调用该方法,并且其行为的定义不太严格。但更重要的是,如果您测试私有方法,您将无法在以后重构代码。因此测试应仅针对公共代码进行。
答案 1 :(得分:1)
KLE是对的。
但是,如果您正在使用遗留代码并且必须处理私有方法中的依赖项,则最后一个选项是JMockit。我没有使用它,但在The Art of Unit Testing中阅读了它。它应该能够将原始类的调用交换到假类。
使用它来破坏对其他对象的依赖性,以便您可以测试公共方法,而不是测试私有方法。并且在重构为分离设计的过程中将其用作安全网。
答案 2 :(得分:0)
如果您还没有使用它,这可能是一个延伸...但Groovy非常适合违反单元测试的访问限制...您可以直接进入并调用方法,就好像它们是公开的而无需额外的反射。
答案 3 :(得分:0)
我很好奇你打包范围方法时会得到什么样的警告,但无论如何,解决这类问题的方法是使测试成为对象的静态内部类。这可能需要权衡;如果部署规模是一个重要问题,您可能需要排除使用代码打包的类,并且需要注意将测试框架中的依赖项意外地引入到生产代码中。
另一个可能的选择是使用一个静态内部类来帮助公开你需要的方法,测试会将它用作私有方法的传递。这里的缺点是这个类基本上将私有方法公开给任何想要使用该类的人,所以你必须小心清楚地表明这个类仅用于测试目的。
答案 4 :(得分:0)
您可以考虑使用reflection。