【问题标题】:Java, Junit - Capture the standard input / Output for use in a unit test [duplicate]Java,Junit - 捕获标准输入/输出以用于单元测试[重复]
【发布时间】:2011-01-11 06:39:51
【问题描述】:

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

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

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

【问题讨论】:

  • @dfa,我不同意。确实很相似,但又足够不同。
  • ...答案是一样的...
  • 另一个线程现在有了更好的答案。它涉及到 jUnit StandardOutputStreamLog 系统规则的使用。 stderr 和 stdin 也有系统规则。

标签: java junit integration-testing io


【解决方案1】:

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

例如:

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

// test stuff here...

final String standardOutput = myOut.toString();

【讨论】:

  • 那么简单地去PrintStream _out = System.out; 行不通吗?
  • 它会 - 即你有一个对现有输出流的引用 - 但你不能从它读取任何东西,因为没有合适的方法可以这样做通用PrintStream 接口。该技术涉及将输出设置为您知道如何读取的特定打印流。
【解决方案2】:

System 类具有方法 setIn()setOut()setErr(),允许您设置标准输入、输出和错误流,例如发送至ByteArrayOutputStream,您可以随意查看。

【讨论】:

    【解决方案3】:

    这是代替 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
        }
    };
    

    这是一个使用类的例子:

    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
    

    【讨论】:

      猜你喜欢
      • 2014-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-29
      • 1970-01-01
      • 2012-05-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多