How to test a print method in Java using Junit

37,787

Solution 1

Since you have put you don't get what the duplicate question says, I will try to explain a little.

When you do, System.setOut(OutputStream), whatever the application writes to the console (using System.out.printX()) statements, instead get written to the outputStream you pass.

So, you can do something like,

public void printTest() throws Exception {
      ByteArrayOutputStream outContent = new ByteArrayOutputStream();
      System.setOut(new PrintStream(outContent));

      // After this all System.out.println() statements will come to outContent stream.

     // So, you can normally call,
     print(items); // I will assume items is already initialized properly.

     //Now you have to validate the output. Let's say items had 1 element.
     // With name as FirstElement and number as 1.
     String expectedOutput  = "Name: FirstElement\nNumber: 1" // Notice the \n for new line.

     // Do the actual assertion.
     assertEquals(expectedOutput, outContent.toString());
}

Solution 2

The best way to test it is by refactoring it to accept a PrintStream as a parameter and you can pass another PrintStream constructed out of ByteArrayOutputStream and check what is printed into the baos.

Otherwise, you can use System.setOut to set your standard output to another stream. You can verify what is written into it after the method returns.

A simplified version with comments is below:

@Test
public void printTest() throws Exception {
    // Create our test list of items
    ArrayList<Item> items = new ArrayList<Item>();
    items.add(new Item("KDM", 1810));
    items.add(new Item("Roy", 2010));

    // Keep current System.out with us
    PrintStream oldOut = System.out;

    // Create a ByteArrayOutputStream so that we can get the output
    // from the call to print
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    // Change System.out to point out to our stream
    System.setOut(new PrintStream(baos));

    print(items);

    // Reset the System.out
    System.setOut(oldOut);

    // Our baos has the content from the print statement
    String output = new String(baos.toByteArray());

    // Add some assertions out output
    assertTrue(output.contains("Name: KDM"));
    assertTrue(output.contains("Name: Roy"));

    System.out.println(output);
}

Note that if the print method throws an exception, the System.out is not reset. It is better to use setup and teardown methods to set and reset this.

Solution 3

How about something like this.

@Test
    public void printTest() throws Exception {
        OutputStream os = new ByteArrayOutputStream();
        System.setOut(os);
        objectInTest.print(items);
        String actualOutput = os.toString("UTF-8");
        assertEquals(expectedOutput, actualOutput);
    }
Share:
37,787
Roy
Author by

Roy

Updated on January 29, 2020

Comments

  • Roy
    Roy over 4 years

    I have written a method that is printing output to a console. How should I test it?

    public class PrinterForConsole implements Printer<Item>{
    
       public void printResult(List<Item> items) {
            for (Item item: items){
                System.out.println("Name: " + item.getName());
                System.out.println("Number: " + item.getNumber());
    
                }
            }
    }
    

    currently, my test looks like this

    public class TestPrinter{
        @Test
        public void printResultTest() throws Exception {
                (am figuring out what to put here)
    
            }
    }
    

    I have read the solution at this post (thanks @Codebender and @KDM for highlighting this) but don't quite understand it. How does the solution there test the print(List items) method? Hence, asking it afresh here.