0

I am creating JUnit and testing the method below:

public static String readLine() throws IOException{

   BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
   return stdin.readLine();
}

I want to make the input string in the JUnit test method in advance, not in readLine() by getting inputput in console by myself.

How can I do that?

Jessy
  • 11
  • 2
  • Unit Tests are automated, repeatable tests for quick feedback, why do you want to obscure that by taking user input, better you create fix set of values you want to try in UT itself and use those, or if you really want it to be external, use some csv, property file kind of thing – sagarr Jun 10 '17 at 09:28
  • 1
    Possible duplicate of [Testing console based applications/programs - Java](https://stackoverflow.com/questions/4230402/testing-console-based-applications-programs-java) – Stefan Birkner Jun 10 '17 at 13:25

3 Answers3

2

You can mock the the inputstream using something like Mockito. But it can also be done without this. Using System.setIn() you can change the stream that System.in will return.

public class ReaderTest {

    @Test
    public void test() throws IOException {
        String example = "some input line"; //the line we will try to read
        InputStream stream = new ByteArrayInputStream((example+"\n").getBytes(StandardCharsets.UTF_8)); //this stream will output the example string
        InputStream stdin = System.in; //save the standard in to restore it later
        System.setIn(stream); //set the standard in to the mocked stream
        assertEquals(example, Reader.readLine()); //check if the method works
        System.setIn(stdin);//restore the stardard in
    }

}

class Reader{
    public static String readLine() throws IOException{
       BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
       return stdin.readLine();
    }
}

Another advantage of mocking the stream is that you don't have to enter the String anymore everytime you want to run the test.

Also note that restoring System.in can be done in a before and after method if you plan on doing this a lot.

Thijs Steel
  • 1,190
  • 7
  • 16
0

Mock the class and then use when and thenReturn to return input instead of taking it from console.

An example of the same is given below,

@Test
    public void readLine() throws Exception {
        BufferedReader bufferedReader = org.mockito.Mockito.mock(BufferedReader.class);
        Mockito.when(bufferedReader.readLine()).thenReturn("line1", "line2", "line3");
    }
Naruto
  • 4,221
  • 1
  • 21
  • 32
0

The library System Rules provides the rule TextFromStandardInputStream for simulating input in JUnit tests.

public class YourClassTest {
  @Rule
  public TextFromStandardInputStream systemInMock = emptyStandardInputStream();

  @Test
  public void test() {
    systemInMock.provideLines("first line", "second line");
    String line = YourClass.readLine();
    assertEquals("first line", line);
  }
}

For details have a look at the System Rules documentation. Disclaimer: I'm the author of System Rules.

Stefan Birkner
  • 24,059
  • 12
  • 57
  • 72