You should not be messing with System.in
during a unit test.
Ask yourself what it is you're testing. Are you testing the Scanner
code, or the code that uses whatever values are entered by the user?
Your code probably does 3 things:
- Ask user for input
- Perform operation
- Display result
In a unit test, you're testing the operation, not the user prompting or the display logic. Or if you do, they should be 3 different unit tests, and remember that if you're testing the user prompting, you're testing the use of the Scanner
, not whether the Scanner can read System.in
.
So, first split your code to:
public class MyClass {
public static void main(String[] args) {
Input input = promptUserForInput(new Scanner(System.in), System.out);
Result result = performOperation(input);
printResult(System.out, result);
}
// methods here
}
You don't have to create new classes for Input
and Result
if they are simple values. They could also be the same class, e.g. an instance of MyClass
.
This way you can test if the operation works for various inputs, which is your primary concern.
@Test
public void testOperation1() {
Input input = new Input(5, 15, true); // true means subtract
Result result = MyClass.performOperation(input);
assertEquals(-10, result.getValue());
}
@Test
public void testOperation2() {
Input input = new Input(5, 15, false); // false means add
Result result = MyClass.performOperation(input);
assertEquals(20, result.getValue());
}
You can also test user prompting and result printing, if needed.
@Test
public void testPrompt() {
String userInput = "5 15\nYes";
PrintStream out = new PrintStream(new ByteArrayOutputStream());
Input input = MyClass.promptUserForInput(new Scanner(userInput), out);
assertEquals(5, input.getNum1());
assertEquals(15, input.getNum2());
assertTrue(input.isSubtractRequested());
}
@Test
public void testPrint() {
ByteArrayOutputStream buf = new ByteArrayOutputStream();
try (PrintStream out = new PrintStream(buf)) {
MyClass.printResult(out, new Result(-10));
}
String outText = new String(buf.toByteArray());
assertEquals("Result is -10\r\n", outText);
}