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

时间:2010-01-30 20:32:32

标签: java junit integration-testing io

我正在使用JUnit编写集成测试,以自动化基于控制台的应用程序的测试。该应用程序是家庭作业,但这部分不是作业。我希望自动化这些测试以提高工作效率 - 我不想再返回并重新测试已经测试过的应用程序部分。 (使用单元测试的标准原因)

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

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

3 个答案:

答案 0 :(得分:45)

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

例如:

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

// test stuff here...

final String standardOutput = myOut.toString();

答案 1 :(得分:7)

System类包含方法setIn()setOut()setErr(),可让您设置标准输入,输出和错误流,例如到你可以随意检查的ByteArrayOutputStream

答案 2 :(得分:2)

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

/**
 * 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
    }
};

以下是使用该类的示例:

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