【发布时间】:2010-08-30 19:03:42
【问题描述】:
假设我们正在设计一个 Stack 类 test-first (TDD):
public class Stack<T> {
private T[] elements = new T[16];
private int size = 0;
...
}
此堆栈使用大小为 16 的内部数组来存储其元素。在您需要添加第 17 个元素之前,它会正常工作。因为我可能需要第 17 个元素,所以我决定将这个功能添加到我的堆栈中,所以我开始考虑我可以为必须添加该功能的测试起什么名字。这将是我第一个问题的主题。
我首先选择了以下形式的东西:
Should_Be_Able_To_Correctly_Increase_Its_Inner_Array_Size()
然后
Should_Handle_More_Items_Than_The_Default_Internal_Array_Size()
但经过一番思考后,我得出的结论是,也许像下面这样更合适:
Should_Double_Its_Size_Every_Time_Its_Full()
我的推理在第一种情况下必须这样做,我只说它做什么,而不是什么时候。 其次,我是在说何时添加更多项目,但我也在说明我是如何考虑实现它的(内部),这可能不正确。在我看来(我不确定我是否正确),我的测试应该是我的 SUT 与外部的可能交互,而不是它是如何在内部实现的。我说的对吗?
在我看来,第 3 个选项是最好的,因为它清楚地说明了它的作用(变大——实际上,它的大小翻了一番),什么时候做(当它满了)并且不束缚我到任何特定的实现(我可能稍后想将其更改为内部 ArrayList!)。
这让我想到了我的第二个问题:假设我为我的 Stack 类执行了所有单元测试,该类在内部使用了一个数组,并且它工作正常并且如预期的那样,如果我的测试保持不变,如果我以后想要重构并将 Array 更改为 ArrayList 或任何其他类型的数据结构?或者测试是否应该以任何方式反映这一点?我猜没有,但我不确定。
【问题讨论】:
-
在我看来,您的测试不应该对内部工作做出假设。如果稍后您选择更改一些内部实现细节,您就不必重写所有测试。
标签: unit-testing testing tdd test-first