Class SystemErrRule

java.lang.Object
org.junit.contrib.java.lang.system.SystemErrRule
All Implemented Interfaces:
org.junit.rules.TestRule

public class SystemErrRule extends Object implements org.junit.rules.TestRule
The SystemErrRule intercepts the writes to System.err. It is used to make assertions about the text that is written to System.err or to mute System.err.

Assertions

SystemErrRule may be used for verifying the text that is written to System.err.

 public class SystemErrTest {
   @Rule
   public final SystemErrRule systemErrRule = new SystemErrRule().enableLog();

   @Test
   public void test() {
     System.err.print("some text");
     assertEquals("some text", systemErrRule.getLog());
   }
 }
 

If your code under test writes the correct new line characters to System.err then the test output is different at different systems. getLogWithNormalizedLineSeparator() provides a log that always uses \n as line separator. This makes it easy to write appropriate assertions that work on all systems.

 public class SystemErrTest {
   @Rule
   public final SystemErrRule systemErrRule = new SystemErrRule().enableLog();

   @Test
   public void test() {
     System.err.print(String.format("some text%n"));
     assertEquals("some text\n", systemErrRule.getLogWithNormalizedLineSeparator());
   }
 }
 

If your code under test writes raw binary data to System.err then you can read it by means of getLogAsBytes()).

 public class SystemErrTest {
   @Rule
   public final SystemErrRule systemErrRule = new SystemErrRule().enableLog();

   @Test
   public void test() {
     byte[] data = { 1, 2, 3, 4, 5 };
     System.err.write(data, 0, data.length);
     assertEquals(data, systemErrRule.getLogAsBytes());
   }
 }
 

You don't have to enable logging for every test. It can be enabled for specific tests only.

 public class SystemErrTest {
   @Rule
   public final SystemErrRule systemErrRule = new SystemErrRule();

   @Test
   public void testWithLogging() {
     systemErrRule.enableLog()
     System.err.print("some text");
     assertEquals("some text", systemErrRule.getLog());
   }

   @Test
   public void testWithoutLogging() {
     System.err.print("some text");
   }
 }
 

If you want to verify parts of the output only then you can clear the log during a test.

 public class SystemErrTest {
   @Rule
   public final SystemErrRule systemErrRule = new SystemErrRule().enableLog();

   @Test
   public void test() {
     System.err.print("uninteresting things");
     systemErrRule.clearLog()
     System.err.print("interesting things");
     assertEquals("interesting things", systemErrRule.getLog());
   }
 }
 

Muting

Usually the output of a test to System.err does not have to be visible. It may even slowdown the test. SystemErrRule can be used to suppress this output.

 public class SystemErrTest {
   @Rule
   public final SystemErrRule systemErrRule = new SystemErrRule().mute();

   @Test
   public void test() {
     System.err.print("some text"); //is not visible on the console
   }
 }
 

You don't have to mute System.err for every test. It can be muted for specific tests only.

 public class SystemErrTest {
   @Rule
   public final SystemErrRule systemErrRule = new SystemErrRule();

   @Test
   public void testWithSuppressedOutput() {
     systemErrRule.mute()
     System.err.print("some text");
   }

   @Test
   public void testWithNormalOutput() {
     System.err.print("some text");
   }
 }
 

In case of a failed test it is sometimes helpful to see the output. This is when the method muteForSuccessfulTests() comes into play.

 public class SystemErrTest {
   @Rule
   public final SystemErrRule systemErrRule = new SystemErrRule().muteForSuccessfulTests();

   @Test
   public void testWithSuppressedOutput() {
     System.err.print("some text");
   }

   @Test
   public void testWithNormalOutput() {
     System.err.print("some text");
     fail();
   }
 }
 

Combine Logging and Muting

Logging and muting can be combined. No output is actually written to System.err but everything that would have been written is available from the log.

 public class SystemErrTest {
   @Rule
   public final SystemErrRule systemErrRule = new SystemErrRule().mute().enableLog();

   @Test
   public void test() {
     System.err.print("some text"); //is not visible on the console
     assertEquals("some text", systemErrRule.getLog()); //succeeds
   }
 }
 
  • Field Details

  • Constructor Details

    • SystemErrRule

      public SystemErrRule()
  • Method Details

    • mute

      public SystemErrRule mute()
      Suppress the output to System.err.
      Returns:
      the rule itself.
    • muteForSuccessfulTests

      public SystemErrRule muteForSuccessfulTests()
      Suppress the output to System.err for successful tests only. The output is still written to System.err for failing tests.
      Returns:
      the rule itself.
    • clearLog

      public void clearLog()
      Clears the current log.
    • getLog

      public String getLog()
      Returns the text that is written to System.err since enableLog() (respectively clearLog() has been called.
      Returns:
      the text that is written to System.err since enableLog() (respectively clearLog() has been called.
    • getLogWithNormalizedLineSeparator

      public String getLogWithNormalizedLineSeparator()
      Returns the text that is written to System.err since enableLog() (respectively clearLog() has been called. New line characters are replaced with a single \n.
      Returns:
      the normalized log.
    • getLogAsBytes

      public byte[] getLogAsBytes()
      Returns the raw bytes that are written to System.err since enableLog() (respectively clearLog() has been called.
      Returns:
      the raw bytes that are written to System.err since enableLog() (respectively clearLog() has been called.
    • enableLog

      public SystemErrRule enableLog()
      Start logging of everything that is written to System.err.
      Returns:
      the rule itself.
    • apply

      public org.junit.runners.model.Statement apply(org.junit.runners.model.Statement base, org.junit.runner.Description description)
      Specified by:
      apply in interface org.junit.rules.TestRule