Мне нужно написать тест JUnit для следующего метода (упрощенно):
/** Return name of previous entry or name of given entry if no previous entry. */
public String getPreviousName(TreeEntry entry) {
if (entry.getPrevious() != null) {
return entry.getPrevious().getName();
} else {
return entry.getName();
}
}
Я просто не знаю, как мне это проверить.Я мог бы либо
a) Использовать Mocks для макетирования параметра и его предыдущей записи, либо
b) Создать настоящую TreeEntry и ее настоящую предыдущую запись
Проблема с использованиемв том, что мне нужно сказать в тестовом примере, какой метод должна использовать фактическая реализация, например, здесь я говорю, что правильное имя получается через getPrevious () TreeEntry, а затем через getName () этой предыдущей записи (не учитываяесли NULL, потому что это в принципе не проблема):
TreeEntry mockEntry = mock(TreeEntry.class);
TreeEntry mockPreviousEntry = mock(TreeEntry.class);
when(mockEntry.getPrevious()).thenReturn(mockPreviousEntry);
when(mockPreviousEntry.getName()).thenReturn("testName");
assertEquals("testName", classUnderTest.getPreviousName(mockEntry));
Но разработчик может, например, также реализовать это так:
return NameService.getName(entry.getPrevious());
Это просто не имеет значения дляtest.
Однако, если я использую классическое модульное тестирование без макетов, у меня возникает другая проблема.Конструктор TreeEntry очень сложен.Он имеет 5 параметров, которые нуждаются в действительных объектах.Поэтому очень сложно создать что-то вроде:
TreeEntry entry = new TreeEntry(...);
TreeEntry previousEntry = new TreeEntry(...);
entry.setPrevious(previousEntry);
previousEntry.setName("testName");
assertEquals("testName", classUnderTest.getPreviousName(entry));
Код будет гораздо длиннее, потому что конструкторы принимают сложные параметры.Другое дело, что конструктор обращается к файловой системе для загрузки оттуда своего содержимого, поэтому он добавляет к замедлению модульных тестов.
Используя классический подход, он также намного больше привязывает тест к реализации TreeEntry,Потому что, если что-то изменилось в TreeEntry с помощью конструкторов или настроек предыдущей записи, это также необходимо будет изменить в тесте.И если он будет забыт, это приведет к сбою теста, даже если тестируемый класс не является TreeEntry.
Что бы вы сказали, как правильно провести модульное тестирование этого?
Я лично склонен кбольше нравится издевательский подход.Можно ли сказать, что в тестовом примере я уже указал, кто является соавторами тестируемого класса, потому что это в некотором роде также больше относится к дизайну, чем к реализации?
С наилучшими пожеланиями, Алекс