繁体   English   中英

System.out的JUnit测试

[英]JUnit test for System.out

这个问题已经在2009年被提出过( JUnit测试System.out.println() )。 有两个“主要”解决方案:

  1. 使用ByteArrayOutputStream()
  2. 使用系统规则(第三方)。

阅读System Rules API后,它看起来更容易使用。

问题是,经过网上快速搜索后,它似乎不太受欢迎。

2017年为System.out进行JUnit测试最受欢迎的方法是什么?

我认为2017年的答案应该是这样的:

  • 你可以使用ByteArrayOutputStream
  • 您可以使用第三方库,例如系统规则
  • 您改进了设计,以避免需要进行依赖于从System.out获取内容的单元测试

Github 表明 系统规则似乎仍然“活着”(在决定是否使用第三方库时总是一个好兆头) - 并且存在8年意味着它可能是一个成熟的产品。 所以:当你添加这个外部依赖对你来说没问题时,就去吧。

但当然:真正的答案仍然是:避免编写这样的测试。 没有什么比查找“错误”更糟糕的了,因为传统的单元测试突然失败了 - 因为某些输出消息包含一个空格而不是一个标签都是出于某些愚蠢的原因。 含义:编写直接发出字符串的代码,并进行单元测试检查。

然后进行单个集成/功能测试,确保你的“管道”是正确的,并且这样的“发出”字符串在某些时候最终会在System.out中出现。

鉴于OP的评论 - 这正好强调了我的观点。 问题是这样的代码:

Scanner scanner = new Scanner(System.in);
if (scanner.next().equals("whatever")) {
  System.out.println("well"));
}

它与System.in和System.out有直接依赖关系。 因此,为了测试上面的代码,人们以某种方式操纵System.in和System.out。 现在看看这段代码:

 public class InOutExample {
   private final Scanner scanner;
   private final OutputStream out;

   public InOutExample() {
     this(new Scanner(), System.out);
   }
   /** unit test only */
   InOutExample(Scanner scanner, OutputStream out) {
     this.scanner = scanner;
     this.out = out;
   }

   public void foo() {
     if (scanner.next().equals("whatever")) {
       out.println("well"));
     }
   }

以上允许您完全单元测试您的foo()方法。 为什么? 因为你可以通过任何扫描仪resp。 将对象放入您想要的示例类中。 您可以编写自己的存根实现了两个对象,或者你嘲笑的对象,并使用你的模拟框架的验证功能检查准确预期的字符串被发送到特殊的OutputStream out

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM