JUnit test for System.out.println() JUnit test for System.out.println() java java

JUnit test for System.out.println()


using ByteArrayOutputStream and System.setXXX is simple:

private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();private final ByteArrayOutputStream errContent = new ByteArrayOutputStream();private final PrintStream originalOut = System.out;private final PrintStream originalErr = System.err;@Beforepublic void setUpStreams() {    System.setOut(new PrintStream(outContent));    System.setErr(new PrintStream(errContent));}@Afterpublic void restoreStreams() {    System.setOut(originalOut);    System.setErr(originalErr);}

sample test cases:

@Testpublic void out() {    System.out.print("hello");    assertEquals("hello", outContent.toString());}@Testpublic void err() {    System.err.print("hello again");    assertEquals("hello again", errContent.toString());}

I used this code to test the command line option (asserting that -version outputs the version string, etc etc)

Edit:Prior versions of this answer called System.setOut(null) after the tests; This is the cause of NullPointerExceptions commenters refer to.


I know this is an old thread, but there is a nice library to do this: System Rules
Example from the docs:

public void MyTest {    @Rule    public final SystemOutRule systemOutRule = new SystemOutRule().enableLog();    @Test    public void overrideProperty() {        System.out.print("hello world");        assertEquals("hello world", systemOutRule.getLog());    }}

It will also allow you to trap System.exit(-1) and other things that a command line tool would need to be tested for.


Instead of redirecting System.out, I would refactor the class that uses System.out.println() by passing a PrintStream as a collaborator and then using System.out in production and a Test Spy in the test. That is, use Dependency Injection to eliminate the direct use of the standard output stream.

In Production

ConsoleWriter writer = new ConsoleWriter(System.out));

In the Test

ByteArrayOutputStream outSpy = new ByteArrayOutputStream();ConsoleWriter writer = new ConsoleWriter(new PrintStream(outSpy));writer.printSomething();assertThat(outSpy.toString(), is("expected output"));

Discussion

This way the class under test becomes testable by a simple refactoring, without having the need for indirect redirection of the standard output or obscure interception with a system rule.