#java #unit-testing #switch-statement #try-finally
#java #модульное тестирование #switch-оператор #try-finally
Вопрос:
Как я должен написать тест для getUrl
метода?
public class UrlList {
private final String[] urls;
private int index;
private SecureRandom random;
public static enum Mode {
VALUE_1,
VALUE_2,
VALUE_3;
}
public UrlList(String... urls) {
if (urls == null || urls.length == 0) {
throw new IllegalArgumentException("The url list may bot be null or empty!");
}
this.urls = urls;
this.index = 0;
this.random = new SecureRandom();
}
public String getUrl(Mode mode) {
switch (mode) {
case VALUE_1:
return urls[0];
case VALUE_2:
return urls[random.nextInt(urls.length)];
case VALUE_3:
try {
return urls[index];
} finally {
index = (index 1) % urls.length;
}
default:
throw new RuntimeException("Unknown mode!");
}
}
}
В приведенном выше коде urls
есть массив строк.
Главный вопрос в том, как я должен протестировать case VALUE_3:
?
Потому что в первый раз протестируйте index = 0
, но после этого значение index
изменится на что-то другое в finally
блоке, и я хочу снова протестировать его с новым index
значением в том же классе модульного тестирования.
Комментарии:
1. Во-первых, если вы собираетесь выполнить
try-finally
блок, вам нужно создать исключение в определении вашей функции.2. Я не понимаю, что вы подразумеваете под «Потому что в первый раз протестируйте
nextUrlIndex = 0
, но после …»3. Спасибо тейлоркресси. Но что вы думаете о главном вопросе 😉
4. Чтобы протестировать метод, вам нужна спецификация для этого метода: тест сравнивает фактическое поведение метода с указанным поведением. Таким образом, никто не может сказать вам, как протестировать ваш метод, если вы не предоставите нам спецификацию для вашего метода.
5. Извините, ребята, я отредактировал приведенный выше код. Это правильный код. Перед первым запуском индекс равен нулю, но, например, если вы запускаете метод во второй или третий раз, индекс не равен 0, он меняется в блоке finally
Ответ №1:
Рассматривали ли вы возможность создания нового экземпляра вашего класса (инкапсулирующего index amp; getURL) для каждого метода тестирования? Таким образом, каждый метод тестирования начинается заново с index = 0 …
Комментарии:
1. Привет, Пелит, я меняю код, чтобы теперь вы могли видеть весь класс.
2. Я сделал это, но тестовый класс может просто протестировать «case VALUE_3: «, когда индекс равен 0. Но как насчет того, когда индекс изменится, и я хочу протестировать его снова?
Ответ №2:
Для ваших тестов вы должны иметь возможность установить значение частной index
переменной равным (например) :
- значение положительное и меньше, чем
urls.length
для управления, которое вы получаетеindex 1
url.length -1
для управления вы получаете 0- ошибочное значение (отрицательное, большее или равное
urls.length
) для управления вы получаете приемлемое (после восстановления после исключения)
Конечно, index является закрытым, но вы все равно можете получить доступ через reflexion
urlList = new UrlList(...); // in test initialization
...
Field index = UrlList.class.getDeclaredField("index");
index.setAccessible(true);
index.setInt(urlList, i); // to set index
i = index.getInt(urlList); // to get index