如何使用 Junit 在 Java 中测试打印方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32241057/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 12:12:22  来源:igfitidea点击:

How to test a print method in Java using Junit

javaunit-testingtestingjunit

提问by Roy

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.

我已经阅读了这篇文章中的解决方案(感谢 @Codebender 和 @KDM 强调这一点),但不太明白。那里的解决方案如何测试 print(List items) 方法?因此,在这里重新提问。

回答by Dakshinamurthy Karra

The best way to test it is by refactoring it to accept a PrintStreamas a parameter and you can pass another PrintStreamconstructed out of ByteArrayOutputStreamand check what is printed into the baos.

测试它的最好方法是重构它以接受 aPrintStream作为参数,您可以传递另一个PrintStream构造的ByteArrayOutputStream并检查打印到 baos 中的内容。

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

否则,您可以使用System.setOut将标准输出设置为另一个流。您可以在方法返回后验证写入的内容。

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 printmethod throws an exception, the System.outis not reset. It is better to use setupand teardownmethods to set and reset this.

请注意,如果该print方法抛出异常,System.out则不会重置。最好使用setupteardown方法来设置和重置它。

回答by Anand Dwivedi

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()

更多信息:System.out.println() 的 JUnit 测试

回答by Jose Martinez

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);
    }

回答by Codebender

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 outputStreamyou pass.

当您这样做时System.setOut(OutputStream),无论应用程序写入控制台(使用System.out.printX())语句,而是写入outputStream您传递的内容。

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());
}

回答by Roy

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.

阅读命名约定 (shouldPrintToConsole()) 以进行测试。想知道这是否是惯例,因为我看到许多遵循的网站和许多没有遵循的网站。