我知道这些网站上的许多帖子[1,2]都在讨论是否应该直接或间接测试私人方法。
我似乎无法理解的是,我怎样才能测试一个类所在的类 -
3个私有方法,由10种不同的公共方法接近。
让我们说私有方法对其特定的数据结构进行排序,或者以一种只与该类相关的特殊方式从中检索一个值(我不打算在每个场景中创建一个内部类)。
现在,如果我选择间接测试私有,那么我每次测试公共方法时都必须重新编写私有逻辑的测试,以便完全测试方法并保持单元测试独立 (并不总是可以在测试相互代码的测试类中创建私有方法) 我将要写一个重复代码和长测试方法。
那么间接测试如何作为标准?
答案 0 :(得分:2)
在我看来,促进你的课程及其方法的低耦合和高内聚是迄今为止TDD最重要的贡献(比#34更有意义;验证代码按预期工作")。
在你强迫自己对每种方法(或多或少)进行单元测试之前,这一点并不明显。只需使私有方法包可见(在这种情况下打破封装是合理的)。
例如,您很快就会发现,测试一个接受参数并返回一些内容的方法会更容易,而不依赖于(或影响)类状态。显然情况并非总是这样,但是足够分解问题,你将拥有更多可测试(且更易读)的代码。
当设计与类状态紧密耦合并且无法解耦时,模拟框架可以节省生命(这可以在所有命令式语言中发生)。例如,您可以在运行测试之前用模拟实例替换(再次打包 - 可见)字段的值。确保验证模拟上的调用!间谍活动也是合理的,但我个人更愿意将其作为最后的手段。
总之,可能。换句话说,如果编写测试很难,请考虑重构代码;)
答案 1 :(得分:1)
私有方法是一个实现细节。您的测试应侧重于:
您应该通过以下两种策略之一验证所有功能。
这基本上分解为第一点:
x
,y
调用方法z
,那么它应该返回a
x
,y
调用方法z
,那么当我读取属性a
时,它应该具有值b
或第二次
x
,y
调用方法z
,那么它应该使用参数a
y+z
如果您的测试属于这种风格,那么更改内部实现将对测试没有影响(即测试不会很脆弱),除非更改是改变类与其依赖项交互的方式,在这种情况下,无论如何,测试都必须改变。
你应该没有理由需要测试类的内部因素,因为如果不能从外部看到它的内部结构(直接通过读取属性,或通过调用具有某些特定参数的另一个方法间接看到它)看到该方法调用的结果受到先前创建的内部状态的影响,或者它与其依赖项的交互,那么它就无关紧要了。
鉴于你的具体例子,听起来你在游戏中有不同的责任。你有一些课负责进行排序(一个Sorter
?),它应该是你主类的依赖。然后,您可以单独测试排序类以验证它是否符合您的预期(上面的类型1测试),然后在此类上使用类型2测试,以确保类调用您提供的Sorter
以确保元素是正确排序。
以这种方式破坏事物不仅可以提供可测试性,还意味着您有可能在其他地方重复使用分拣机。
答案 2 :(得分:1)
我同意您链接的用户eis(请参阅上面的评论)from the answer in a thread:
真正的答案是,如果你有测试私人方法的冲动,那么该方法不应该是私有的;如果让方法公开困扰你,那么很可能是因为它是一个单独的责任的一部分;它应该在另一个班级。
尽量避免测试私有方法。它们应该只使代码更具可读性。如果私有方法变得如此复杂以至于应该进行单元测试,请将其提取到一个新类中,然后您可以正确/轻松地进行单元测试。