Search code examples
javaeclipsejunituser-input

JUnit testing with simulated user input


I am trying to create some JUnit tests for a method that requires user input. The method under test looks somewhat like the following method:

public static int testUserInput() {
    Scanner keyboard = new Scanner(System.in);
    System.out.println("Give a number between 1 and 10");
    int input = keyboard.nextInt();

    while (input < 1 || input > 10) {
        System.out.println("Wrong number, try again.");
        input = keyboard.nextInt();
    }

    return input;
}

Is there a possible way to automatically pass the program an int instead of me or someone else doing this manually in the JUnit test method? Like simulating the user input?


Solution

  • You can replace System.in with you own stream by calling System.setIn(InputStream in). InputStream can be a byte array:

    InputStream sysInBackup = System.in; // backup System.in to restore it later
    ByteArrayInputStream in = new ByteArrayInputStream("My string".getBytes());
    System.setIn(in);
    
    // do your thing
    
    // optionally, reset System.in to its original
    System.setIn(sysInBackup);
    

    Different approach can be make this method more testable by passing IN and OUT as parameters:

    public static int testUserInput(InputStream in,PrintStream out) {
        Scanner keyboard = new Scanner(in);
        out.println("Give a number between 1 and 10");
        int input = keyboard.nextInt();
    
        while (input < 1 || input > 10) {
            out.println("Wrong number, try again.");
            input = keyboard.nextInt();
        }
    
        return input;
    }