I'm trying to unit test a main method that takes input from the keyboard. I know there are several questions on SO about testing keyboard input and the use of System.setIn(...) to do so, but it only works for the first input for me.
My code:
public class TestApp {
@Test
public void testMain() {
InputStream stdin = System.in;
try {
System.setIn(new ByteArrayInputStream("s\r\nx\r\n".getBytes()));
String args[] = {};
App.main(args);
// TODO: verify that the output is what I expected it to be
}
catch(IOException e) {
assertTrue("Unexpected exception thrown: " + e.getMessage(), false);
}
finally {
System.setIn(stdin);
}
}
}
What I'm trying to achieve is to input 's' and then 'x' (two different entries).
When using the program normally, it should output stuff after pressing 's' followed by the enter key, and output something else after pressing 'x'. The main method looks like this:
class App {
public static void main(String[] args) throws IOException {
int choice;
do {
choice = getChar();
switch(choice) {
case 's':
System.out.println("Text for S");
break;
case 'x':
System.out.println("Exiting");
break;
}
} while(choice != 'x');
}
public static String getString() throws IOException {
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
String s = br.readLine();
return s;
}
public static char getChar() throws IOException {
String s = getString();
return s.charAt(0);
}
}
Note: I know the best way to achieve it is to inject an InputStream dependency and use it instead of System.in, but I can't change the code. This is a restriction I have, I can't change main(), getString() or getChar() methods.
When I execute the test, this is the output:
Text for S
java.lang.NullPointerException
at App.getChar(tree.java:28)
at App.main(tree.java:7)
at TestApp.testMain(TestApp.java:15) <23 internal calls>
So, it looks like it gets the first input ('s'), but not the second one...
Any help greatly appreciated.