JUnit testing with simulated user input

Wimpey picture Wimpey · Jun 20, 2011 · Viewed 96.5k times · Source

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?

Thanks in advance.

Answer

KrzyH picture KrzyH · Jun 20, 2011

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;
}