JUnit Testing - 将void类型方法的stdout输出与String进行比较

时间:2016-12-28 17:35:52

标签: java unit-testing junit

我想测试一个将String写入stdout的void类型方法。 对于这个问题,我和我的团队正在尝试将其输出与我们在调用方法时期望看到的字符串/文本进行比较。

注意:我是Java和StackOverflow的新手,所以如果有更好的方法,我会很感激收到通知。

 public static boolean test_printAdequateOption(String txt, double[]
 sol, Formatter out, String expectedOutput) {
         //Obj.
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         PrintStream ps = new PrintStream(baos);
         PrintStream sout = System.out;

         System.setOut(ps);

         printAdequateOption(txt, sol, out);

         System.out.flush();
         System.setOut(sout);



     return  baos.toString().equals(expectedOutput);
 }

这个测试背后的想法是将printAdequateOption方法的输出打印到PrintStream,这样它就可以将它保存为String,从而将它与预期的输出参数进行比较。

2 个答案:

答案 0 :(得分:3)

我建议您重构代码,使其更易于测试。显然,你的方法printAdequateOption(...)都格式化/创建字符串,然后调用System.out.println()(或类似的东西)。

您并不真正关心测试打印到标准输出的JDK调用是否适用于正确的输入,但您有兴趣检查将要打印的字符串是否具有预期的格式。所以基本上你需要将字符串创建/格式化提取到一个单独的方法,该方法将返回格式化的字符串。这种方法的测试应该是直截了当的。

答案 1 :(得分:0)

第一:

  1. 命名:你只在SOME_CONSTANT中使用_ char;所以你的方法最好被称为testPrintAdequateOption()
  2. 使测试本身成为JUnit @Test;然后;而不是返回一个布尔值;你在测试代码中做了一个真正的断言;以便测试真正失败意外结果(见下文有关如何做到这一点)
  3. 如果你真的想保持这种方式,这个名字有点误导。你宁愿调用你的方法doesPrintAdequateOptionGiveCorrectResultsOn()或类似的东西:返回布尔值的方法应该在它们的名字中指出它们是关于的,这是一个布尔选择!
  4. 从纯技术角度来看,上面的代码是可以的。除了一个设计问题...如果测试内容写入stdout只是"只有"测试代码的方法;那么你应该考虑使真正的测试成为可能。

    换句话说:你的考试是你能做的最好的;但你打算测试的东西;分别是你必须这样做的事实......这是真正的问题!

    编辑:我忽略了你真的要求JUnit单元测试。因此,我们给出一个更好的答案,并简单地说明真正的 JUnit测试应该如何显示:

    @Test
    public boolean testPrintAdequateOption() {   
         // overwrite stdout to allow for capturing print statement
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         PrintStream ps = new PrintStream(baos);
         PrintStream sout = System.out;
         System.setOut(ps);
    
         // call method with specific input
         String text = ...
         double[] sol = ...
         Formatter formatter = ...
         printAdequateOption(text, sol, formatter);
    
         System.out.flush();
         System.setOut(sout);
    
         assertThat(baos.toString(), is("expected output));
      }
    

    这就是合理测试的样子;使用JUnit执行;例如在你的eclipse IDE中。

    请注意:我正在使用 assertThat 断言,以及 hamcrest匹配器。有关这两个内容,请参阅here

    有趣的是:当你编写这样的测试时,很明显你应该简单地改变你的逻辑;正如tomkab在他的回答中所暗示的那样 - 你不希望printAdequateOption()产生一个字符串并将其打印到System.out。相反,您需要一个可以直接生成该字符串的方法。所以没有像你在代码中那样绕道而行!