mbauer
mbauer

Reputation: 345

JUnit test user input with Mockito

I have a problem with the Mocking Framework Mockito. I want to test the input the user types in the console. Without Mocking it works great but with it I don't know how to get the return value from the function which get's the input in the console.

Without Mockito:

Read input method

public int readUserInput() {
    BufferedReader console = new BufferedReader(new InputStreamReader(
            System.in));
    return Integer.parseInt(console.readLine());
    ...
}

Test method:

public class TestClass {
    Controller contr = new Controller();
    @Test
    public void testUserInput() {
        System.setIn(new ByteArrayInputStream("1".getBytes()));
        assertEquals(1, contr.readUserInput());
        System.setIn(System.in);
    }
}

But now how to write the test with Mockito. I tried several ways but none of them worked. I got all the time a 0 and not the number I wrote in the ByteArrayInputStream.

Thanks in advance!

Upvotes: 0

Views: 3090

Answers (2)

Stefan Birkner
Stefan Birkner

Reputation: 24510

You can use the TextFromStandardInputStream rule of the System Rules library instead of Mockito. It ensures that System.in is always resetted after the test. (Your code doesn't reset System.in in case of a failing assert.)

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

  Controller contr = new Controller();

  @Test
  public void testSomething() {
    systemInMock.provideText("1");
    assertEquals(1, contr.readUserInput());
  }
}

Upvotes: 0

ppuskar
ppuskar

Reputation: 771

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.

Upvotes: 3

Related Questions