Junit Test For System.Out.Println()

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;

@Before
public void setUpStreams() {
System.setOut(new PrintStream(outContent));
System.setErr(new PrintStream(errContent));
}

@After
public void restoreStreams() {
System.setOut(originalOut);
System.setErr(originalErr);
}

sample test cases:

@Test
public void out() {
System.out.print("hello");
assertEquals("hello", outContent.toString());
}

@Test
public 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.

JUnit test failed for testing system.out.println result

The expected output string that you are trying to assert should be

0\n1\n0\n

as there is a println.

Corrected unit test method should be as below.

    @Test
public void test() {
CountNumP2 cn = new CountNumP2();
cn.countUpDown(0, 1);
String output = "0\n1\n0\n";
Assert.assertEquals(output , outContent.toString());
}

System.out.print() doesn't show anything in test methods

Use Log

private static Logger log = Logger.getLogger(LoggingObject.class);
log.info("I'm starting");

or System.setOut()

private final PrintStream stdout = System.out;
private final ByteArrayOutputStream output = new ByteArrayOutputStream();
private TerminalView terminalview;

Junit test for println

The problem is indeed the different line separators for Windows, I updated your fragment, I replaced \n with + System.lineSeparator()

Locally on my Mac it works I expect it to be fine on Windows too with this change.

public static void hello(){
System.out.println("Hello");
}


@Test void Test(){
System.setOut(new PrintStream(outContent));
System.setErr(new PrintStream(errContent));

hello();

// Changed the line below
assertEquals("Hello" + System.lineSeparator(), outContent.toString());

System.setIn(System.in);
System.setOut(originalOut);
System.setErr(originalErr);
}

JUnit test for System.out

I think the 2017 answer should read like this:

  • you can use a ByteArrayOutputStream
  • you can use 3rd party libraries such as System Rules
  • you improve your design to avoid the need to do unit testing that relies on fetching content from System.out

Github shows that System Rules still seems "alive" (which is always a good sign when deciding if to use a 3rd party library) - and being around for 8 years implies that it is probably a mature product. So: when adding this external dependency is fine for you, just go for it.

But of course: the real answer still is: avoid writing such tests. There is nothing worse but hunting "bugs" because a legacy unit test fails all of a sudden - because some output message contains a space instead of a tab all for some stupid reason. Meaning: write code that emits Strings directly, and have unit tests check those.

Then have a single integration/function test that makes sure that your "plumbing" is correct, and that such "emitted" strings end up in System.out at some point.

Given the comment by the OP - which exactly underlines my point. The problem is code like this:

Scanner scanner = new Scanner(System.in);
if (scanner.next().equals("whatever")) {
System.out.println("well"));
}

which has direct dependencies to System.in and System.out. So, in order to test the above code, one has somehow manipulate System.in and System.out therefore. Now look at this code:

 public class InOutExample {
private final Scanner scanner;
private final OutputStream out;

public InOutExample() {
this(new Scanner(), System.out);
}
/** unit test only */
InOutExample(Scanner scanner, OutputStream out) {
this.scanner = scanner;
this.out = out;
}

public void foo() {
if (scanner.next().equals("whatever")) {
out.println("well"));
}
}

The above allows you to fully unit test your foo() method. Why? Because you can pass any scanner resp. out object into the example class that you want. You can either write your own stub implementation for the two objects, or you mock the objects and use the verification capabilities of your mocking framework to check that exactly the expected strings are sent to that special OutputStream out!

Testing System.out.println not working but System,out.print using JUnit

Try this

String expected = "hellohello again " + System.getProperty("line.separator");
assertEquals(expected, outContent.toString());

Testing println output with JUnit

Make sure that your line separator is equal to \n on your system.
This is not the case on Windows.

To fix the test, modify it to take system-specific separator into account

assertEquals("Hello World" + System.lineSeparator(), outContent.toString());


Related Topics



Leave a reply



Submit