Scalatest - cómo probar println

¿Hay algo en Scalatest que me permita probar la salida a la salida estándar a través de un println ¿declaración?

Hasta ahora he estado usando principalmente FunSuite with ShouldMatchers.

por ejemplo, ¿cómo comprobamos la salida impresa de

object Hi {
  def hello() {
    println("hello world")
  }
}

preguntado el 28 de agosto de 11 a las 00:08

3 Respuestas

Si solo desea redirigir la salida de la consola por una duración limitada, use el withOut y withErr métodos definidos en 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")
}

Respondido 28 ago 11, 12:08

Este es mucho mejor, no es necesario reestructurar su programa para las pruebas. - BorisOkunskiy

La forma habitual de probar declaraciones de impresión en la consola es estructurar su programa de manera un poco diferente para que pueda interceptar esas declaraciones. Por ejemplo, puede introducir un Output rasgo:

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

  class Hi extends Output {
    def hello() = print("hello world")
  }

Y en tus pruebas puedes definir otro rasgo MockOutput realmente interceptando las llamadas:

  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")

Respondido 29 ago 11, 03:08

Necesitas agregar override a MockOutput - Amir Raminfar

Me gusta mucho esta solución, @Eric hay una manera de hacer esto sin tener que extender Output. yo siento extending un rasgo, donde ese rasgo no es necesario en primer lugar, es un truco. Tendría sentido si el rasgo ya fuera necesario y creáramos un impl de prueba. - Amir Raminfar

La única otra forma de evitar extender un rasgo es hacer lo que Kevin o Matthieu recomiendan. Dicho esto, tengo la filosofía de que construir su software para que sea comprobable es una buena decisión de diseño. Cuando persigues ese pensamiento, vas hasta el final para introducir rasgos para todos sus interacciones de E / S / sistemas externos. - Eric

@eric yo no diría que yo estaba del asesoramiento La redirección es una buena forma de escribir pruebas unitarias, simplemente señalando que es una posibilidad si, por ejemplo, necesita adaptar las pruebas al código existente y desea ser mínimamente invasivo. Odiaría cambiar el código no probado más de lo que estaba estrictamente necesario; incluso si is con el fin de facilitar la incorporación de dichas pruebas - Kevin Wright

override útil pero no necesario - juanchito

Puede reemplazar el lugar donde println escribe usando Console.setOut (PrintStream)

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

Obviamente, puede usar cualquier tipo de transmisión que desee. Puede hacer lo mismo para stderr y stdin con

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

Respondido 28 ago 11, 11:08

Tenga en cuenta que Console.{setErr, setIn, setOut} han quedado obsoletos a partir de 2.11.0 (~ 3 años después de que se envió esta respuesta). - Rusty Shackleford

Los nuevos métodos son Console. {WithOut, withIn, withErr} - Zee

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.