假设我们正在设计一个 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 类进行了所有单元测试,并且它工作正常并且如预期的那样,如果我以后想要重构并将数组更改为ArrayList 或任何其他类型的数据结构?或者测试是否应该以任何方式反映这一点?我猜没有,但我不确定。