【问题标题】:JUnit test for System.outSystem.out 的 JUnit 测试
【发布时间】:2017-08-01 13:32:54
【问题描述】:

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

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

阅读 System Rules API 后,看起来使用起来更简单、更友好。

问题是,在网上快速搜索后,似乎不是很受欢迎。

2017 年对 System.out 进行 JUnit 测试最被接受的方法是什么?

【问题讨论】:

    标签: java junit console


    【解决方案1】:

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

    • 您可以使用 ByteArrayOutputStream
    • 您可以使用 3rd 方库,例如 System Rules
    • 您改进您的设计以避免需要进行依赖于从System.out 获取内容的单元测试

    Github shows System Rules 似乎仍然“活跃”(这在决定是否使用 3rd 方库时总是一个好兆头)- 存在 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() 方法进行单元测试。为什么?因为你可以通过 any 扫描仪。将对象放入您想要的示例类中。您可以为这两个对象编写自己的存根实现,或者模拟这些对象并使用模拟框架的 验证 功能来检查是否将预期的字符串准确地发送到该 special 输出流out!

    【讨论】:

    • 当我需要经常与用户“交谈”时,这是如何工作的,即用户有很多决定需要手动输入作为输入 (system.in),程序应该打印出下一步做什么(system.out)。我可以调用一个获取输入并打印它的函数,但我不明白这一点。我想我只是没有完全理解你。你写的第一件事真的很有帮助
    猜你喜欢
    • 2011-09-19
    • 2014-03-21
    • 1970-01-01
    • 1970-01-01
    • 2018-03-23
    • 1970-01-01
    • 2023-04-08
    • 2010-11-10
    • 2016-08-21
    相关资源
    最近更新 更多