How can I test against console input automaticly by mocking?
Please take a look at the example:
@RunWith(MockitoJUnitRunner.class)
public class TestClass {
@Mock
ConsoleReaderWriter crw;
@InjectMocks
UnderTestClass underTest;
//Some other fields
@Test
public void testReadPlayerNameShouldReturnNameString() {
String testName = "John Doe";
when(crw.readLine()).thenReturn("John Doe");
assertEquals(testName, underTest.readPlayerName());
}
}
JUnit testing with simulated user input
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;
}
JUnit test for console input and output
Ideally, extract the awkward dependencies so that you can test without them. Change main
to simply:
public static void main(String[] args) {
doWork(new Scanner(System.in), System.out);
}
// TODO: Rename to something meaningful
public static void doWork(Scanner input, PrintStream output) {
// Remainder of code
}
(Consider using a Writer
instead of a PrintStream
for output
.)
Then you don't really need to unit test main
- but you can test doWork
using a Scanner
based on a StringReader
, and output based on a StringWriter
, providing whatever input you want and checking the output.
JUnit test user input with Mockito
You need to Mock BufferedReader
's readLine()
API to return your value.
i.e
Mockito.when(mockedBufferedReader.readLine())
.thenReturn("1");
Now when you call the readInput() from the Test then your mocked buffered reader's API will be invoked.Hope this answers your question.
Test functions with JUnit where functions get user input
Don't use a static field for the Scanner
. It stores the reference to the System.in
when it is created the first time. Setting System.in
again to a different value in the second test does not change the Scanner
's System.in
. Change your class code like this fixes your test.
private Scanner scanner = new Scanner(System.in);
By the way you should restore System.in
after the test. I've written a library named System Rules that makes it even easier to write tests for code that reads from System.in
.
Related Topics
How to Refresh or Reload the Jframe
How to Get the Path of Src/Test/Resources Directory in Junit
Java Program to Find Palindrome Numbers in Given Range
How to Save a File Downloaded With Httpclient into a Specific Folder
Spring Boot @Autowired Environment Throws Nullpointerexception
Java Properties - How to Create Dynamic Properties
Passing Data into HTML from Java Via Spring
How to Return Different Results When Calling the Same Mocked Method
Org.Hibernate.Annotationexception: @Onetoone or @Manytoone on <Entity> References an Unknown Entity
Method Does Not Override Method from Its Superclass . Android Fragment
How to Check Heap Usage of a Running Jvm from the Command Line
Spring Boot API Call With Multiple @Requestparam
Java.Io.Filenotfoundexception: the System Cannot Find the File Specified
How to Resolve Java.Lang.Noclassdeffounderror: Javax/Xml/Bind/Jaxbexception
Java Syntax Error on Token.... Identifier Expected After This Token