Search code examples
javajunitmockingmockitobufferedreader

Mock bufferedReader.readline() stubbing not working


My project requires user to input a command line in the console. I used bufferedreader.readline() to capture user input. My bufferedreader is in a while loop so it will keep reading new command and process it.

Class View bufferedreader will keep reading line if input is not "Q"

For my test, I created a mock bufferedreader in order to stub bufferedreader.readline to return a command.

`@Test
    void whenCommandIsR_CallBuildRectangle() throws IOException {
    View view = new View();
    BufferedReader bufferedReader = mock(BufferedReader.class);

    when(bufferedReader.readLine()).thenReturn("C 10 10").thenReturn("Q");

    view.inputCommand();
    verify(bufferedReader, times(2)).readLine();
 }`

When I run the test, the console is stuck at bufferedreader.readline(), the console shows waiting for input

I expect the stubbing to work but it did not. Are there any ways to force the return for bufferedreader.readline?

Please assist. Thank you!


Solution

  • Based on the screenshot you provided I can see that the BufferedReader is instantiated inside the View class as a final field, hence the View object will use that instance of BufferedReader, instead of your mock.

    I would assume that you are not using any kind of dependency injection mechanism for this.

    Make the BufferedReader field a constructor parameter and pass the mock inside when creating a View object inside your testcase.

    @Test
    void whenCommandIsR_CallBuildRectangle() throws IOException {
        BufferedReader bufferedReader = mock(BufferedReader.class);
        when(bufferedReader.readLine()).thenReturn("C 10 10").thenReturn("Q");
        View view = new View(bufferedReader);
    
        view.inputCommand();
        verify(bufferedReader, times(2)).readLine();
     }