Test System.out with JUnit

Edit: see also the follow up article on how to Test log4j with JUnit if you’re interested in specifically testing log output.

Just occasionally, it can be useful to verify output to System.out in a unit test. For example, if you’re testing application logging or if you’re using log output to sense some other behaviour. It can be tricky to properly mock behaviour of System.out but fortunately, it is possible to test System.out with JUnit.

Here’s a simple Spring MVC Controller:

Ignoring tests for the obvious behaviours here (method return value, password hashing and account creation), lets focus instead on testing the log output. We want to verify the results of the log.warn and log.info calls. Our options are:

  1. Replace the Logger instance with a mock. This would be easier if it were injected ( @Autowired) into the class but it’s still possible – Powermock can do this.
  2. Replace System.out with a mock. Logger writes to console via System.out by default so if we can mock System.out, we can verify logging. This technique is shown below.

Replacing System.out with a mock

By default, System.out is a PrintStream, typically connected to the console. It can however be replaced with any other instance of PrintStream using System.setOut(PrintStream out). If we replace it with a PrintStream backed by a byte array, we can verify all writes to System.out by inspecting the byte array. Here’s an example of a test that uses this technique:

Note that we maintain the original instance of System.out and put it back after the test is finished. This is required so that subsequent tests properly log to console rather than our byte array.

Using a JUnit @Rule

This technique is fine for a one-off test but will require copy and pasting of the @Before (setup) and @After (teardown) methods if it’s to be used in other tests. To make this technique reusable in other tests, we can use a JUnit @Rule. System.out is an external resource that needs to be set up before a test and torn down afterward so let’s sublcass JUnit’s ExternalResource class:

This simplifies our test class which now looks like this:

The test code for these examples is in GitHub:


  • Pingback: Test log4j with JUnit using a custom appender - Don't Panic!

  • Pingback: Test log4j2 with JUnit using a custom appender - Don't Panic!

  • September 21, 2019 - 3:50 am | Permalink

    This is failing not working for cases with a carriage return(\r) or newline(\n) in sysout. Do we need to take care of anything else here?

  • Leave a Reply

    Your email address will not be published. Required fields are marked *