据我了解,大多数人似乎都同意不应直接测试私有方法,而应通过任何公共方法对其进行测试。我可以理解他们的观点,但是当我尝试遵循“ TDD的三个定律”并使用“红色-绿色-重构”循环时,我对此有一些疑问。我认为最好用一个例子来解释:
现在,我需要一个程序,该程序可以读取文件(包含制表符分隔的数据)并过滤掉包含非数值数据的所有列。我想可能已经有一些简单的工具可以做到这一点,但是我决定从头开始实现它,主要是因为我认为这对我来说是一个不错的,干净的项目,可以进行TDD的实践。
因此,首先,我“戴上红色帽子”,也就是说,我需要测试失败。我想,我需要一种可以找到一行中所有非数字字段的方法。因此,我编写了一个简单的测试,当然它无法立即编译,因此我开始编写函数本身,并且在来回循环(红色/绿色)之后,我有了一个有效的函数和一个完整的测试。
接下来,我继续使用函数“ gatherNonNumericColumns”,一次读取文件,并在每一行调用我的“ findNonNumericFields”功能以收集最终必须删除的所有列。几个红绿色循环,我完成了,又一次具有工作功能和完整的测试。
现在,我认为我应该重构。由于我的方法“ findNonNumericFields”仅是因为我认为实现“ gatherNonNumericColumns”时需要它而设计的,所以在我看来,让“ findNonNumericFields”成为私有是合理的。但是,这将中断我的第一个测试,因为他们将无法再访问他们正在测试的方法。
因此,我最终得到了一个私有方法,以及一组测试它的测试。既然有很多人建议不要测试私有方法,那感觉就像我在这里陷入困境。但是我到底在哪里失败了?
我认为我本可以从更高的级别开始,编写一个测试以测试最终将成为我的公共方法的方法(即findAndFilterOutAllNonNumericalColumns),但这感觉与TDD的整个观点有些矛盾(至少根据Bob叔叔的说法) :您应该在编写测试和生产代码之间不断切换,并且在任何时间点,所有测试都在最后一分钟左右进行。因为如果我从为公共方法编写测试开始,那么在私有方法中获得所有详细信息之前,将需要几分钟(甚至几小时,甚至几天)才能使该方法测试公共方法通过。
那么该怎么办?TDD(具有快速的红绿色重构周期)是否与私有方法不兼容?还是我的设计有问题?
private
好像这样做有意义。