单元测试私有内部类方法

时间:2015-06-28 14:56:52

标签: java unit-testing mockito jmock

我有一个A类,它有一个由B类代表的内部Cache。这个内部类是私有的,因为缓存不需要对外部使用者可见,只是为了帮助外部类A.我使用的是Jmock和Java

public class A {
    ...
    private class B {
    ... 
       public void testMethod() {
          //The method I want to unit test
          ...
       }
    }
}

如上所示。我不确定如何对来自私有内部类B的testMethod()进行单元测试(因为B类对于外部世界是不可见的)。

请指教!

谢谢!

4 个答案:

答案 0 :(得分:7)

  

因为外部消费者无法看到缓存

单元测试是外部消费者。它就像一个其他类一样调用被测对象的功能。

警告: 关于这个问题有很多意见和争论。我在这里展示的并不是一个真正的答案"但是基于我自己在代码中维护单元测试的经验。

不要直接对私人会员进行单元测试。它不仅通常需要一点点诡计才能实现,它会在类之间创建耦合。 (测试类和正在测试的类。)暴露内部和耦合它们违反了面向对象的原则。

不要根据您在课堂上调用的方法考虑您的测试,而是根据您在单元上调用的功能来考虑您的测试。无论该单元暴露什么功能都应该测试什么。

这导致了一些结论:

  • 如果没有内部调用相关私人成员的公共功能,那么为什么那些私人成员呢?只需删除它们。
  • 如果私有功能非常复杂并且很难仅使用公共功能来调用/验证,那么可能需要进行一些重构以简化类。

由于使用该对象的代码只能调用公共功能,因此测试该对象的代码只应验证公共功能。

答案 1 :(得分:3)

不建议对私有方法/类进行单元测试。测试调用私有方法的父方法就足够了。尽管如此,你可以断言/验证私有类的影响。

例如,

如果你的内部类正在改变数据库中的某个值,你可以调用父方法并且可以对db值进行断言。这可以确保你的私有方法/私有内部类被测试。

参考:unit testing private methods

答案 2 :(得分:3)

如果您严格遵循TDD方法,私有方法和私有内部类只是red/green/refactor周期中重构步骤的结果。

所以方法应该是:

  1. 编写用于测试类的公共接口的测试,包括此缓存行为,并编写代码以便随时通过这些测试。这将导致长公共方法和一些显然仅与缓存相关的字段。
  2. 然后从长公共方法中重构出一些与缓存相关的私有方法。
  3. 下一步应该是将私有缓存字段和方法移动到私有内部类。每次重构后,测试都应该通过而无需修改。
  4. 您将完成仍然经过全面测试的私有方法,但只能通过公共界面完成。

答案 3 :(得分:1)

如上所述,您应该重新考虑为什么要测试私有方法,我不会再这样做,因为其他方法已经提供了一些很好的信息。

但是,如果仍需要测试私有方法,请使用反射来解锁"私有方法,并使用Apache Commons避免编写公共代码(DRY - Don&#ttt tt You Yourself) https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/reflect/package-summary.html

如果需要模拟私有方法,例如在类的私有方法中完成的数据库调用。同样最好的方法是重新设计它以便数据库组件被抽象出来,但如果你必须这样做,请考虑PowerMock

https://code.google.com/p/powermock/wiki/MockPrivate