Один из распространенных способов проверки подобного кода - извлечь метод, который использует Scanner и PrintWriter, аналогично этому ответу StackOverflow , и проверить, что:
public void processUserInput() {
processUserInput(new Scanner(System.in), System.out);
}
/** For testing. Package-private if possible. */
public void processUserInput(Scanner scanner, PrintWriter output) {
output.println("Give a number between 1 and 10");
int input = scanner.nextInt();
while (input < 1 || input > 10) {
output.println("Wrong number, try again.");
input = scanner.nextInt();
}
return input;
}
Обратите внимание, что вы не сможете прочитать свой вывод до конца, и вам придется указать все ваши входные данные заранее:
@Test
public void shouldProcessUserInput() {
StringWriter output = new StringWriter();
String input = "11\n" // "Wrong number, try again."
+ "10\n";
assertEquals(10, systemUnderTest.processUserInput(
new Scanner(input), new PrintWriter(output)));
assertThat(output.toString(), contains("Wrong number, try again.")););
}
Конечно, вместо того, чтобы создавать метод перегрузки, вы также можете оставить «сканер» и «вывод» в качестве изменяемых полей в тестируемой системе. Я предпочитаю держать классы без гражданства, насколько это возможно, но это не очень большая уступка, если это имеет значение для вас или ваших коллег / инструктора.
Вы также можете поместить тестовый код в тот же пакет Java, что и тестируемый код (даже если он находится в другой папке с исходным кодом), что позволяет ослабить видимость перегрузки двух параметров как частной для пакета .