Я создал интерактивное Java-приложение, используя класс Scanner. Я хочу проверить это с помощью Junit 5.
После поиска, но я написал тестовый пример для имитации оболочки. Тестовый пример выполняется для первой команды и остается в основном методе. Это не возвращает консоль наружу. Мои последующие команды не выполняются из-за этого.
public static void main(String[] args) {
final Scanner scanner = new Scanner(System.in);
while (true) {
final String input = scanner.nextLine();
if (input.equalsIgnoreCase("exit")) {
printMsg("Exiting the application..");
System.exit(1);
}
else {
printMsg("User Input >>>> " + input);
final CommandProcessor commandProcessor = new CommandProcessor();
try {
commandProcessor.process(input);
}
catch (Exception e) {
System.out.println("An error occurred - " e.getLocalizedMessage() + ". Please try again.");
}
}
}
}
public class CommandProcessor {
public void process(final String input) throws Exception {
//Some validations
final CommandHandler commandHandler = CommandHandlerFactory.getHandler(inputCommand);
commandHandler.execute(args);
}
}
}
public class CreateCommandHandler extends CommandHandler {
@Override
void handle(final String[] args) throws Exception {
final int units = Integer.parseInt(args[1]);
System.out.println("Created units " + units);
}
}
class ApplicationTest {
private static final InputStream systemIn = System.in;
private static final PrintStream systemOut = System.out;
private static InputStream testIn;
private static OutputStream testOut;
@BeforeEach
public void setUpOutput() {
testOut = new ByteArrayOutputStream();
System.setOut(new PrintStream(testOut));
}
private void provideInput(String data) {
testIn = new ByteArrayInputStream(data.getBytes());
System.setIn(testIn);
}
private String getOutput() {
return testOut.toString();
}
@AfterEach
public void resetSystemInputOutput() {
System.setIn(systemIn);
System.setOut(systemOut);
}
@Test
public void testCreateSuccess() {
String testString = "create 2";
provideInput(testString);
Application.main(new String[0]);
assertEquals("Created units - 2", getOutput());
//Verifying the empty state. Another handler is invoked for it.
provideInput("status");
assertEquals("No units assigned", getOutput());
//exiting the shell.
provideInput("exit");
}
// @Test
public void testStatusAfterCreateParkingLotSuccess() {
String testString = "status";
provideInput(testString);
Application.main(new String[0]);
assertEquals(AppConstants.PARKING_LOT_IS_EMPTY, getOutput());
resetSystemInputOutput();
provideInput("exit");
Application.main(new String[0]);
}
@AfterAll
public static void exit() {
//System.setIn(new ByteArrayInputStream("exit".getBytes()));
}
}
Юнит-тест testCreateSuccess () запускает только команду create, а затем продолжает ожидать следующего ввода. Элемент управления не возвращается к тесту для отправки следующей команды. Почему он ведет себя по-другому здесь? Когда я запускаю оболочку, я могу вводить команды 1 на 1. Как я могу добиться того же поведения в тестовых примерах? Есть 5-6 команд, которые мне нужно запустить и проверить с помощью Junit. Любая помощь приветствуется. Я также хочу обработать эти команды из текстового файла.