2011-08-28 90 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