【问题标题】:Scalatest - how to test printlnScalatest - 如何测试 println
【发布时间】:2011-11-05 07:30:48
【问题描述】:

Scalatest 中有什么东西可以让我通过println 语句将输出测试到标准输出吗?

到目前为止,我主要使用FunSuite with ShouldMatchers

例如我们如何检查

的打印输出
object Hi {
  def hello() {
    println("hello world")
  }
}

【问题讨论】:

    标签: scala scalatest


    【解决方案1】:

    如果您只想在有限的时间内重定向控制台输出,请使用Console 上定义的withOutwithErr 方法:

    val stream = new java.io.ByteArrayOutputStream()
    Console.withOut(stream) {
      //all printlns in this block will be redirected
      println("Fly me to the moon, let me play among the stars")
    }
    

    【讨论】:

    • 这个更好,无需为测试重新构建程序。
    【解决方案2】:

    在控制台上测试打印语句的通常方法是稍微不同地构建程序,以便您可以截获这些语句。例如,您可以引入 Output 特征:

      trait Output {
        def print(s: String) = Console.println(s)
      }
    
      class Hi extends Output {
        def hello() = print("hello world")
      }
    

    在您的测试中,您可以定义另一个特征 MockOutput 实际拦截调用:

      trait MockOutput extends Output {
        var messages: Seq[String] = Seq()
    
        override def print(s: String) = messages = messages :+ s
      }
    
    
      val hi = new Hi with MockOutput
      hi.hello()
      hi.messages should contain("hello world")
    

    【讨论】:

    • 您需要将override添加到MockOutput
    • 我非常喜欢这个解决方案,@Eric 有没有办法做到这一点而无需扩展 Output。我觉得extending 一个特征,首先不需要该特征,这是一种黑客行为。如果该 trait 已经被需要并且我们创建了一个测试 impl,那将是有意义的。
    • 避免扩展特征的唯一其他方法是按照 Kevin 或 Matthieu 的建议进行操作。话虽如此,我的理念是构建可测试的软件是一个好的设计决策。当您追求这种想法时,您会一直为所有您的 IO / 外部系统交互引入特征。
    • @eric 我不会说我是建议重定向作为编写单元测试的好方法,只是指出如果你例如需要对现有代码进行改进测试,并且希望是微创的。我不想更改未经测试的代码,而不是严格必要的;即使它为了更容易添加所述测试
    • override 有用但没必要
    【解决方案3】:

    您可以使用 Console.setOut(PrintStream) 替换 println 写入的位置

    val stream = new java.io.ByteArrayOutputStream()
    Console.setOut(stream)
    println("Hello world")
    Console.err.println(stream.toByteArray)
    Console.err.println(stream.toString)
    

    您显然可以使用任何类型的流。 你可以为 stderr 和 stdin 做同样的事情

    Console.setErr(PrintStream)
    Console.setIn(PrintStream)
    

    【讨论】:

    • 请注意,Console.{setErr, setIn, setOut} 自 2.11.0 起已被弃用(提交此答案后约 3 年)。
    • 新方法是 Console.{withOut, withIn, withErr}
    猜你喜欢
    • 1970-01-01
    • 2023-03-21
    • 2018-08-10
    • 2016-05-12
    • 2019-12-18
    • 2012-07-15
    • 2017-10-22
    • 2020-06-04
    • 1970-01-01
    相关资源
    最近更新 更多