2015-10-17 129 views
1

我想測試一個函數是否能夠使用「os」包的stdout變量打印到標準輸出,實際上是打印到標準輸出。我運行這個函數,我發現它打印到標準輸出。現在我想弄清楚如何證明這個函數使用golang代碼打印到標準輸出。我可以使用「os」包的stdout變量來檢查在調用數組中的某個函數之後stdout是否已被寫入?如何檢查stdout是否已寫入?

我試圖通過調用os.stdout變量的Stat()方法來確定stdout是否已寫入,以便訪問stdout的大小和上次修改時間,但大小和上次修改時間沒有反映出一個函數寫入stdout的事實。

+0

我還沒有嘗試過這樣做,但在Python中,我會使用'unittest.mock.patch'在函數調用的持續時間內向'os.stdout'上monkeypatch不同的bufio,然後讀取bufio後查看是否已寫入。 –

+0

你可以通過一個不同的文件(可能是一個模擬)到你的實現,而不是stdout,你可以斷言嗎? –

+3

從「外部」進行測試,或者使stdout可配置(在測試期間更改它)或者根本不測試這些內容。 – Volker

回答

1

在我看來,正確的處理方法是讓代碼以某種方式將io.Writer作爲參數,而不是直接使用stdout。你真的應該避免打印到標準輸出而無法讓更高級別的代碼重定向它。幾乎所有的stdlib都採用這種方法。很少的stdlib在默認情況下寫入標準輸出,大部分地方都有一個採用Writer的更一般的形式。例如,fmt.Printf is simply a convenience function for fmt.Fprintf.

這就是說,你可以模擬標準輸出。如果你的代碼推送到標準輸出,所有你需要做的是爲標準輸出建立一個全局變量,然後寫入那裏。這是在stdlib測試中完成的,以模擬time.Now()。而不是使用time.Now,他們使用全局的包now(),並根據是否正在運行測試進行設置。

作爲最後的手段,假設前兩件事情是不可能的,你可以複製當前的os.Stdout,並用os.Pipe代替它。然後你需要另一個goroutine來監聽那個管道並報告返回的內容。