2011-08-28 89 views
21

Scalatest中有什么可以让我通过println声明测试输出到标准输出吗?Scalatest - 如何测试println

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

例如我们如何检查

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

回答

24

通常使用的方法打印输出测试打印报表上的控制台来构建程序有点不同,这样就可以截获这些语句。例如,您可以引入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") 
+0

您需要为MockOutput添加'override' –

+0

我非常喜欢这个解决方案,@Eric有办法做到这一点,而不必扩展Output。我觉得'扩展'一个特性,首先不需要这个特性,这是一种破解。如果这个特征已经被需要,我们创建了一个测试impl,这将是有意义的。 –

+3

避免扩大特质的唯一方法是做Kevin或Matthieu建议的内容。话虽如此,我有这样一种理念,即构建软件以使其可测试是一项很好的设计决策。当你追求这个想法时,你会一路引进特征来为所有的你的IO /外部系统交互作用。 – Eric

2

可以更换其中的println使用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) 

显然你可以使用任何你想要的类型的流。 你可以做同样的为标准错误和标准输入的东西与

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

请注意,控制台。{setErr,setIn,setOut}从2.11.0开始已弃用(在提交此答案后约3年)。 –

+0

新的方法是控制台{withOut,withIn,withErr} – Zee

57

如果你只是想重定向在有限的时间控制台输出,使用上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") 
} 
+0

好点,我忘了那个。 – Eric

+3

这是一个更好的方法,不需要重新测试您的程序。 – incarnate