Scalatest - 如何测试println

Lui*_*hys 27 scala scalatest

Scalatest中有什么东西允许我通过println声明测试输出到标准输出吗?

到目前为止,我一直在使用FunSuite with ShouldMatchers.

例如,我们如何检查打印输出

object Hi {
  def hello() {
    println("hello world")
  }
}
Run Code Online (Sandbox Code Playgroud)

Kev*_*ght 73

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

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")
}
Run Code Online (Sandbox Code Playgroud)

  • 这个更好,不需要重新构建您的程序进行测试. (4认同)

Eri*_*ric 27

在控制台上测试打印语句的常用方法是以不同的方式构建程序,以便拦截这些语句.例如,您可以介绍一个Output特征:

  trait Output {
    def print(s: String) = Console.println(s)
  }

  class Hi extends Output {
    def hello() = print("hello world")
  }
Run Code Online (Sandbox Code Playgroud)

在测试中,您可以定义另一个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")
Run Code Online (Sandbox Code Playgroud)

  • 避免延长特质的另一种方法是做Kevin或Matthieu所建议的.话虽如此,我的理念是构建软件以使其可测试是一个很好的设计决策.当你追求这种想法时,你会一直为所有*你的IO /外部系统交互引入特征. (3认同)

Mat*_*ell 6

您可以使用 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)
Run Code Online (Sandbox Code Playgroud)

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

Console.setErr(PrintStream)
Console.setIn(PrintStream)
Run Code Online (Sandbox Code Playgroud)

  • 新方法是 Console.{withOut, withIn, withErr} (4认同)
  • 请注意,`Console.{setErr, setIn, setOut}` 自 2.11.0 起已被弃用(提交此答案后约 3 年)。 (3认同)