在学习“测试驱动开发”时,我从《高效程序员》一书中发现了一个有趣的案例:
You need to find all factors of a "complete number". A complete number is the sum of all its factors (except the one which equals to the number itself) is equal to the number. So
6
is the minimal complete number, and its factors are1, 2, 3
.
如果我想要 TDD,首先我想测试一个最简单的测试用例:
@Test public void completeNumber6() {
CompleteNumber completeNumber = new CompleteNumber(6)
assertEquals(completeNumber.findFactors(), new Int[] {1,2,3});
}
但是!问题是这个最简单的情况将驱动findFactors()
的所有实现,这对我来说似乎太多了。
作者给出了一些建议,我们可以将需求分成几个步骤:
- 检查数字是否是另一个数字的因数
- 提供一种将一些因素收集到集合中的方法
- 检查每个较小的数字,看看它是否是给定数字的因子,然后收集它们
- 检查收集到的因子之和是否等于给定数字
我们可以先进行 TDD 前 2 个步骤:
@Test public void testIsFactor() {}
@Test public void testAddFactor() {}
因此之后会有 2 个公共(public)(至少是非私有(private))方法:
boolean isFactor(Int n1, Int n2)
void addFactor(Int factor)
问题是这两个方法在整个实现之后应该是私有(private),因为它们应该只由findFactors
内部使用!
但是如果将它们更改为私有(private),我们该如何处理它们现有的测试用例呢?
作者建议我们可以将它们改为private,并使用Java refection API来获取和测试它们。听起来可能,但我不确定这样做是否是一个好的做法。
我也问了一些 friend ,他们给出了一些其他的选择:
- 保持方法
isFactor
和addFactor
保持非私有(private)状态,这是可以接受的 - 为 2 个方法提取类
FactorChecker
和FactorCollector
- 将它们更改为私有(private),并删除测试用例,因为它们的功能已在后面的测试用例(步骤 3 和 4)中进行了测试
我现在很困惑,哪种方法才是 TDD 的最佳实践?
最佳答案
在我看来,问题指出这些是完整的数字这一事实有些无关紧要。您可以计算任何整数的因数。因此,考虑到我将从实现 findFactors(1) 开始,然后逐步向上。
这使得它与经典的 Prime Factors Kata 略有不同。 ,唯一的区别是您在因素列表中添加了 1。
关于java - 如何处理单个简单测试用例将驱动整个实现的情况?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33694845/