Java、Junit - 捕获用于单元测试的标准输入/输出

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2169330/
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-13 04:22:45  来源:igfitidea点击:

Java, Junit - Capture the standard input / Output for use in a unit test

javajunitintegration-testingio

提问by Frank V

I'm writing integration tests using JUnit to automate the testing of a console based application. The application is homework but this part isn't the homework. I want to automate these tests to be more productive -- I don't want to have to go back and retest already tested parts of the application. (Standard reasons to use Unit tests)

我正在使用 JUnit 编写集成测试来自动化基于控制台的应用程序的测试。申请是作业,但这部分不是作业。我想自动化这些测试以提高效率——我不想回去重新测试应用程序中已经测试过的部分。(使用单元测试的标准理由)

Anyway, I can't figure out or find an article on capturing the output so that I can do assertEqualson it nor providing automated input. I don't care if the output/input goes to the console/output pane. I only need to have the test execute and verify the the output is what is expected given the input.

无论如何,我无法弄清楚或找到有关捕获输出的文章,以便我可以对其进行assertEquals处理,也无法提供自动输入。我不在乎输出/输入是否进入控制台/输出窗格。我只需要执行测试并验证输出是给定输入的预期结果。

Anyone have an article or code to help out with this.

任何人都有一篇文章或代码来帮助解决这个问题。

采纳答案by Andrzej Doyle

Use System.setOut()(and System.setErr()) to redirect the output to an arbitrary printstream - which can be one that you read from programmatically.

使用System.setOut()(和System.setErr())将输出重定向到任意打印流 - 可以是您以编程方式读取的打印流。

For example:

例如:

final ByteArrayOutputStream myOut = new ByteArrayOutputStream();
System.setOut(new PrintStream(myOut));

// test stuff here...

final String standardOutput = myOut.toString();

回答by Michael Borgwardt

The Systemclass has methods setIn(), setOut()and setErr()that allow you to set the standard input, output and error streams, e.g. to a ByteArrayOutputStreamthat you can inspect at will.

System类有方法setIn()setOut()setErr()允许您的标准输入,输出和错误流,如设为ByteArrayOutputStream您可以将检查。

回答by Val

Here is the solution in place of ByteArrayOutputStream. It does not add anything to the idea of System.setOut. Rather, I want to share the implementation that is better than capturing everything into ByteArrayOutputStream. I prefer to capture only selected information and let all log messages to appear in the console as they are logged rather than capturing everything into a balckbox (of which size?) for later processing.

这是替代 ByteArrayOutputStream 的解决方案。它不会为 System.setOut 的想法添加任何内容。相反,我想分享比将所有内容捕获到 ByteArrayOutputStream 中更好的实现。我更喜欢只捕获选定的信息,并让所有日志消息在记录时显示在控制台中,而不是将所有内容捕获到一个黑匣子(大小?)中以供以后处理。

/**
 * Once started, std output is redirected to this thread. 
 * Thread redirects all data to the former system.out and
 * captures some strings.*/
static abstract class OutputCaputre extends Thread {

    // overrdie these methods for System.err
    PrintStream getDownstream() { return System.out;}
    void restoreDownstream() { System.setOut(downstream);}

    // will be called for every line in the log
    protected abstract void userFilter(String line);

    final PrintStream downstream;
    public final PipedInputStream pis;
    private final PipedOutputStream pos;
    OutputCaputre() throws IOException {
        downstream = getDownstream();

        pos = new PipedOutputStream();
        pis = new PipedInputStream(pos);
        System.setOut(new PrintStream(pos));

        start();
    }

    public void run() {
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(pis));

            // once output is resotred, we must terminate
            while (true) {
                String line = br.readLine();
                if (line == null) {
                    return;
                }
                downstream.println(line);
                userFilter(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void terminate() throws InterruptedException, IOException {
        restoreDownstream(); // switch back to std
        pos.close(); // there will be no more data - signal that
        join(); // and wait until capture completes
    }
};

Here is an example of using the class:

以下是使用该类的示例:

OutputCaputre outputCapture = new OutputCaputre() {
    protected void userFilter(String line) {
        downstream.println("Capture: " + line);
    }       
};
System.out.println("do you see me captured?");
// here is your test    
outputCapture.terminate(); // finally, stop capturing