我有一个类a,它有一个由类B表示的内部缓存。这个内部类是私有的,因为缓存不需要对外部消费者可见,只是为了帮助外部类a。我使用的是Jmock和Java
public class A {
...
private class B {
...
public void testMethod() {
//The method I want to unit test
...
}
}
}
如上图所示。我不知道如何对来自私有内部类B的testMethod()进行单元测试(因为类B对外部世界不可见)。
请告知!
谢谢!
因为缓存不需要对外部消费者可见
单元测试是一个外部使用者。它是一个调用被测试对象功能的类,就像任何其他类一样。
注意: 关于这个问题有很多意见和争论。我在这里介绍的不是"唯一的真实答案",而是基于我自己在代码中维护单元测试的经验
不要直接对私有成员进行单元测试。这不仅通常需要一点技巧才能实现,而且还会在类之间创建耦合。(测试类和正在测试的类。)公开内部和与它们的耦合违反了面向对象的原则。
不要根据在类上调用的方法来考虑测试,而是根据在单元上调用的功能来考虑测试。单元公开的任何功能都应该进行测试。
这导致了一些结论:
- 如果没有在内部调用有问题的私有成员的公共功能,那么为什么会有这些私有成员呢?只要把它们取下来
- 如果私有功能非常复杂,并且仅使用公共功能很难调用/验证,那么可能需要进行一些重构来简化类
由于使用对象的代码只能调用公共功能,因此测试对象的代码应该只验证公共功能。
如果您严格遵循TDD方法,私有方法和私有内部类只是红/绿/重构周期中重构步骤的结果。
因此,方法应该是:
- 编写测试类的公共接口(包括这种缓存行为)的测试,并编写代码在执行时通过这些测试。这将导致长的公共方法和一些显然只与缓存相关的字段
- 然后从长公共方法中重构出一些与缓存相关的私有方法
- 下一步应该是将私有缓存字段和方法移动到私有内部类。每次重构之后,测试都应该在不进行修改的情况下通过
您将以privates方法结束,这些方法仍然经过充分测试,但只能通过公共接口进行测试。
例如
如果您的内部类正在更改数据库中的某个值,则可以调用父方法,并可以针对数据库值进行断言。这样可以确保您的私有方法/私有内部类得到测试。
参考:单元测试私有方法
如上所述,您应该重新思考为什么要测试私有方法,我不再赘述,因为其他人已经提供了一些好的信息。
但是,如果仍然需要测试私有方法,请使用反射来"解锁"私有方法,并使用Apache Commons来避免编写公共代码(DRY-Don't Repeat Yourself)https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/reflect/package-summary.html
如果您需要模拟一个私有方法,例如在类的私有方法中进行的DB调用。同样,最好的方法是重新设计它,使DB组件抽象出来,但如果必须这样做,可以考虑PowerMock
https://code.google.com/p/powermock/wiki/MockPrivate