4

Very very simple class:

public class ConsoleHandler {

    public void write(String message) {
        System.out.println(message);
    }

}

How do I test that when I call write("hello"), System.out.println("hello") is called? And also, is this unit test even worth it?

Jeanne Boyarsky
  • 12,156
  • 2
  • 49
  • 59
Maria Ines Parnisari
  • 16,584
  • 9
  • 85
  • 130

4 Answers4

4

As for whether it is worth testing, it depends on why your are outputting. I usually do test System.out calls when writing command line utilities because that is the user interface and the text output matters. It's not even hard to do - just regular Java code.

The below technique shows how you can capture the values of System.out. You don't even need a mock framework. Note that it stores the "real" System.out so it can put it back at the end. If you don't do this, your other tests/code can quickly become confusing.

import static org.junit.Assert.*;

import java.io.*;

import org.junit.*;

public class ConsoleHandlerTest {

    private PrintStream originalSysOut;
    private ByteArrayOutputStream mockOut;

    @Before
    public void setSysOut() {
        originalSysOut = System.out;
        mockOut = new ByteArrayOutputStream();
        System.setOut(new PrintStream(mockOut));
    }

    @After
    public void restoreSysOut() {
        System.setOut(originalSysOut);
    }

    @Test
    public void outputIsCorrect() {
        new ConsoleHandler().write("hello");
            assertEquals("message output", "hello".trim(), mockOut.toString().trim());
    }

}
Jeanne Boyarsky
  • 12,156
  • 2
  • 49
  • 59
2

No, this unit test is not worth the time or the disk space. Unit testing is to make sure you get logic right. If there's no logic, there is nothing to be gained from the test. Its cost-benefit ratio is infinite.

You should unit test a method if it has branching logic, loops, or exception handling. But if all it does is call another method, then forget it. The best way to find out whether method X calls method Y is to look at the code.

Having said that, if you do insist on testing this, you should use the System.setOut method, passing a ByteArrayOutputStream that you've wrapped in a PrintStream, and then verify the contents of the underlying byte[] at the end.

Dawood ibn Kareem
  • 77,785
  • 15
  • 98
  • 110
0

You can use libraries such as Mockito ( http://code.google.com/p/mockito/ ) to mock classes as well as interfaces.

That said, you shouldn't be using Sysout in the first place. Use a logger such as Log4J or a logging facade such as SLF4J ( http://www.slf4j.org/ ). SLF4J has a testing framework that will make testing easier ( http://projects.lidalia.org.uk/slf4j-test/ )

And of course, JUnit or TestNG to set your test cases up.

Tommy B
  • 187
  • 2
  • 8
0

To your first question "How do I test that when I call write("hello"), System.out.println("hellow") is called?"

You can use Mockito and follow the instructions in this answer: Mockito : how to verify method was called on an object created within a method?

To your second question "is this unit test even worth it?" As the test is, no, it doesn't make sense. However you can use this as a template, checking in the future if any method was called.

Community
  • 1
  • 1
Alexandre Santos
  • 8,170
  • 10
  • 42
  • 64