单元测试私有内部 class 方法

Unit test private inner class methods

我有一个 Class A,它有一个由 Class B 表示的内部缓存。这个内部 class 是私有的,因为缓存不需要对外部消费者可见,并且是只是辅助外层class A.我用的是Jmock和Java

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

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

请指教!

谢谢!

since the cache need not be visible to external consumers

单元测试是外部消费者。它是一个 class 调用被测对象的功能,就像任何其他 class.

警告: 关于这个问题有很多意见和争论。我在这里展示的不是 "the one true answer",而是基于我自己在代码中维护单元测试的经验。

不要直接对私有成员进行单元测试。它不仅通常需要一些技巧才能实现,而且还会在 class 之间创建耦合。 (测试 class 和正在测试的 class。)暴露内部结构并与它们耦合是违反面向对象原则的。

与其根据在 [=39= 上调用的方法来考虑测试,不如根据在 上调用的功能 来考虑测试=23=]单位。该单元公开的任何功能都是应该测试的。

由此得出几个结论:

  • 如果没有 public 内部调用相关私有成员的功能,那么为什么会有这些私有成员呢?只需删除它们。
  • 如果私有功能非常复杂并且很难 invoke/validate 仅使用 public 功能,那么也许进行一些重构是为了简化 class.

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

单元测试私有methods/classes不是recommended.It足以测试调用私有methods.Having的父方法methods.Having说,你可以断言/验证私有class。

例如,

如果你的内部 class 正在改变数据库中的一些值,你可以调用父方法并且可以对数据库进行断言 values.This 确保你的私有 methods/private 内部 classes 接受测试。

参考:unit testing private methods

如上所说,你应该重新考虑一下为什么要测试一个私有方法,我不再赘述,因为其他人已经提供了一些很好的信息。

但是,如果仍然需要测试私有方法,请使用反射 "unlock" 私有方法,并使用 Apache Commons 避免编写公共代码(DRY - 不要重复自己) https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/reflect/package-summary.html

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

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

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

所以方法应该是:

  1. 编写测试 class 的 public 接口的测试,包括此缓存行为,并编写代码以随时通过这些测试。这将导致很长的 public 方法和一些显然只与缓存相关的字段。
  2. 然后从长public方法中重构出一些缓存相关的私有方法。
  3. 下一步应该是将私有缓存字段和方法移动到私有内部 class。每次重构后,测试应该无需修改即可通过。

您将完成仍然经过全面测试的私有方法,但只能通过 public 接口。