Я создал интерактивную оболочку Java-приложения. Я хочу проверить это с помощью Junit 5 - PullRequest
0 голосов
/ 21 октября 2019

Я создал интерактивное 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. Любая помощь приветствуется. Я также хочу обработать эти команды из текстового файла.

...