How to test a print method in Java using Junit [du

2020-07-10 19:49发布

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.

5条回答
欢心
2楼-- · 2020-07-10 20:29

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.

查看更多
够拽才男人
3楼-- · 2020-07-10 20:30

This is the Simple Test Code :-

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

For more :JUnit test for System.out.println()

查看更多
男人必须洒脱
4楼-- · 2020-07-10 20:40

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);
    }
查看更多
聊天终结者
5楼-- · 2020-07-10 20:40

Eventually, what I came up with is this (after going through all the answers and links to possible duplicates above).

import org.junit.Test;
@Test
public void shouldPrintToConsole() throws Exception {
        Item testItem = new Item("Name", "Number");
        List<Item> items = Arrays.asList(testItem);

        Printer print = new Printer();
        printer.printOutput(items);
    }

Read up on naming convention (shouldPrintToConsole()) for testing too. Wondering if this is the convention because I see many sites that follow and many that don't.

查看更多
迷人小祖宗
6楼-- · 2020-07-10 20:41

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());
}
查看更多
登录 后发表回答