2011-08-28 10 views
21

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

Hasta ahora he estado usando principalmente FunSuite with ShouldMatchers.

p. Ej. ¿Cómo podemos comprobar la salida impresa de

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

Respuesta

24

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

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

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

Y en sus pruebas se puede definir otro rasgo MockOutput realidad que interceptan 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") 
+0

Necesita agregar 'anular' a MockOutput –

+0

Me gusta mucho esta solución, @Eric hay una manera de hacerlo sin tener que extender 'Output'. Siento que "extender" un rasgo, donde ese rasgo no es necesario en primer lugar, es un truco. Tendría sentido si el rasgo ya era necesario y creamos una prueba impl. –

+3

La única otra forma de evitar extender un rasgo es hacer lo que Kevin o Matthieu están aconsejando. Dicho esto, tengo la filosofía de que la construcción de su software para que sea comprobable es una buena decisión de diseño. Cuando persigue ese pensamiento, va hasta la introducción de rasgos para * todas * sus interacciones IO/sistemas externos. – Eric

2

Puede reemplazar println donde escribe a mediante el uso de 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 utilizar cualquier tipo de transmisión que desee. Usted puede hacer el mismo tipo de cosas para stderr y la entrada estándar con

Console.setErr(PrintStream) 
Console.setIn(PrintStream) 
+1

Tenga en cuenta que 'Console. {setErr, setIn, setOut}' se han desaprobado a partir de 2.11.0 (~ 3 años después de enviar esta respuesta). –

+0

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

57

Si lo que desea es redirigir la salida de la consola para una duración limitada, utilizar los 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") 
} 
+0

Buen punto, me olvidé de eso. – Eric

+3

Esta es mucho mejor, no es necesario reestructurar su programa para las pruebas. – incarnate

Cuestiones relacionadas