Daniel Paczuski Bak
Daniel Paczuski Bak

Reputation: 4088

Testing a method that reads from standard input and outputs to standard output

I have a method which reads lines from the standard input and writes lines to the standard output.

From within a JUnit test, how can I send input to the method, and how can I capture its output so that I can make assertions on it?

Upvotes: 5

Views: 1378

Answers (1)

Mike Nakis
Mike Nakis

Reputation: 62045

You should not have a method which reads from standard input and writes to standard output.

You should have a method which accepts as parameters the InputStream from which it reads, and the PrintStream into which it writes. (This is an application, at the method level, of a principle known as Dependency Injection (Wikipedia) which is generally used at the class level.)

Then, under normal circumstances, you invoke that method passing it System.in and System.out as parameters.

But when you want to test it, you can pass it an InputStream and a PrintStream that you have created for test purposes.

So, you can use something along these lines:

void testMyAwesomeMethod( String testInput, String expectedOutput )
{
    byte[] bytes = testInput.getBytes( StandardCharsets.UTF_8 );
    InputStream inputStream = new ByteArrayInputStream( bytes );
    StringWriter stringWriter = new StringWriter();
    try( PrintWriter printWriter = new PrintWriter( stringWriter ) )
    {
        myAwesomeMethod( inputStream, printWriter );
    }
    String result = stringWriter.toString();
    assert result.equals( expectedOutput );
}

Upvotes: 18

Related Questions