Давайте предположим, что мы проектируем класс стека первым (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 с внешним миром, а не с тем, как оно реализовано внутри. Я прав?
Мне кажется, что третий вариант - лучший, поскольку в нем четко указано, что он делает (увеличивается в размерах - фактически удваивает свой размер), когда он делает (когда он заполнен) и не связывает меня к любой конкретной реализации (возможно, позже я захочу изменить ее на внутренний ArrayList!).
Что приводит меня к моему второму вопросу : Предполагая, что я выполнил все юнит-тесты для своего класса Stack, который использует внутренний массив, и он работает нормально и, как ожидается, мои тесты останутся нетронутыми, если я позже Хотите реорганизовать и изменить массив на ArrayList или любой другой вид структуры данных? Или тесты должны как-то это отражать? Я думаю, нет, но я не уверен.