我应该单独测试私有方法吗?

时间:2014-10-01 13:53:13

标签: java unit-testing

我知道这些网站上的许多帖子[12]都在讨论是否应该直接或间接测试私人方法。 我似乎无法理解的是,我怎样才能测试一个类所在的类 -
3个私有方法,由10种不同的公共方法接近。

让我们说私有方法对其特定的数据结构进行排序,或者以一种只与该类相关的特殊方式从中检索一个值(我不打算在每个场景中创建一个内部类)。

现在,如果我选择间接测试私有,那么我每次测试公共方法时都必须重新编写私有逻辑的测试,以便完全测试方法并保持单元测试独立 (并不总是可以在测试相互代码的测试类中创建私有方法) 我将要写一个重复代码和长测试方法。

那么间接测试如何作为标准?

3 个答案:

答案 0 :(得分:2)

在我看来,促进你的课程及其方法的低耦合和高内聚是迄今为止TDD最重要的贡献(比#34更有意义;验证代码按预期工作")。

在你强迫自己对每种方法(或多或少)进行单元测试之前,这一点并不明显。只需使私有方法包可见(在这种情况下打破封装是合理的)。

例如,您很快就会发现,测试一个接受参数并返回一些内容的方法会更容易,而不依赖于(或影响)类状态。显然情况并非总是这样,但是足够分解问题,你将拥有更多可测试(且更易读)的代码。

当设计与类状态紧密耦合并且无法解耦时,模拟框架可以节省生命(这可以在所有命令式语言中发生)。例如,您可以在运行测试之前用模拟实例替换(再次打包 - 可见)字段的值。确保验证模拟上的调用!间谍活动也是合理的,但我个人更愿意将其作为最后的手段。

总之,可能。换句话说,如果编写测试很难,请考虑重构代码;)

答案 1 :(得分:1)

私有方法是一个实现细节。您的测试应侧重于:

  • 方法的外部可见行为
  • 您的班级与其依赖关系的互动

您应该通过以下两种策略之一验证所有功能。

这基本上分解为第一点:

  • 如果我使用参数xy调用方法z,那么它应该返回a
  • 如果我使用参数xy调用方法z,那么当我读取属性a时,它应该具有值b

或第二次

  • 如果我使用参数xy调用方法z,那么它应该使用参数a
  • 调用依赖项y+z

如果您的测试属于这种风格,那么更改内部实现将对测试没有影响(即测试不会很脆弱),除非更改是改变类与其依赖项交互的方式,在这种情况下,无论如何,测试都必须改变。

你应该没有理由需要测试类的内部因素,因为如果不能从外部看到它的内部结构(直接通过读取属性,或通过调用具有某些特定参数的另一个方法间接看到它)看到该方法调用的结果受到先前创建的内部状态的影响,或者它与其依赖项的交互,那么它就无关紧要了。

鉴于你的具体例子,听起来你在游戏中有不同的责任。你有一些课负责进行排序(一个Sorter?),它应该是你主类的依赖。然后,您可以单独测试排序类以验证它是否符合您的预期(上面的类型1测试),然后在此类上使用类型2测试,以确保类调用您提供的Sorter以确保元素是正确排序。

以这种方式破坏事物不仅可以提供可测试性,还意味着您有可能在其他地方重复使用分拣机。

答案 2 :(得分:1)

我同意您链接的用户eis(请参阅上面的评论)from the answer in a thread

  

真正的答案是,如果你有测试私人方法的冲动,那么该方法不应该是私有的;如果让方法公开困扰你,那么很可能是因为它是一个单独的责任的一部分;它应该在另一个班级。

尽量避免测试私有方法。它们应该只使代码更具可读性。如果私有方法变得如此复杂以至于应该进行单元测试,请将其提取到一个新类中,然后您可以正确/轻松地进行单元测试。