2011-05-02 125 views
10

有製作C#控制檯應用程序的單位可測試通過編程對一個接口,而不是System.Console的標準呢?嘲諷「System.Console行爲

例如,使用IConsole接口?

您是否已經完成了這項操作,並且您使用了哪種方法?

你暴露當你的應用程序需要寫入到標準輸出的事件?

+0

可能重複[可以用Moq嘲弄嗎?](http://stackoverflow.com/questions/1220454/can-this-be-mocked-with-moq) – Jonathan 2011-05-02 02:05:56

回答

13

我想用一個接口的方法是有效的,而且我不認爲我會利用事件。假設應用程序不接受超過命令行參數的其他用戶輸入,我可能會使用這樣的包裝Console.Write/Console.WriteLine

public interface IConsoleWriter 
{ 
    void Write(string format, params object[] args); 
    void WriteLine(string format, params object[] args); 
} 

爲了測試,我就可以創建一個TestConsoleWriter,將存儲所有寫入的緩衝區然後我可以斷言,否則我會創建一個模擬並驗證WriteWriteLine是否使用我期望的參數進行調用。如果您的應用程序將要大量寫入控制檯(比如說+100 MB左右的輸出),那麼使用模擬可能會更適合性能方面的原因,但除此之外,我會說選擇您認爲的任何一種方法更容易與之合作。

但是,這種方法確實有一些限制。如果您正在使用任何不能修改的程序集並將它們寫入控制檯,那麼您將看不到該輸出,因爲您無法強制這些類使用IConsoleWriter。另一個問題是WriteWriteLine方法有18個左右的重載,所以你可能會包裝很多方法。爲了解決這些限制,您可能只想在測試時使用Console.SetOut方法將控制檯輸出重定向到您自己的TextWriter

就我個人而言,我想我會採取SetOut的方法。在你的單元測試開始時(或者可能在SetUp方法中),你只能添加一行,你可以對寫入TextWriter的內容進行斷言。

+0

來自其他人的很好的答案,但我贊成這一點,因爲它有效地將程序與具體的「控制檯」實例隔離開來,它允許我寫一個純粹的單元測試。其他建議更適合行爲/集成測試。 – Jonathan 2011-05-02 03:41:52

+1

我沒有想到SetOut方法。整齊。 – corlettk 2011-05-02 04:18:51

+0

使用setout/setin修改控制檯行爲時的問題是,它如何與使用控制檯本身的測試框架進行交互。 – annakata 2014-03-05 11:44:56

4

我正好在這個線程昨晚行程:Using reflection to override virtual method tables in C#。由菲利普勞雷亞諾LinFu

@paulo想出了答案。

通過的例子在Philip Laureano's Development Blog: Intercepting Console.WriteLine指導您的使用例子如何攔截調用Console.WriteLine命令的方法,以及(在這種情況下)執行一些額外的操作,以及... AOP的.NET ... Very Noice,恕我直言!

李林甫可能只是門票,因爲它的東西中沒有出現被攔截,這樣你就可以「截取並修改」的電話您的上下文中第三方供應商的組件」行爲「,但是沒有任何可能影響之外的截獲類的實際行爲 ...所以LinFu聽起來像是一個不錯的開始實施」控制檯應用程序的通用測試框架「的好地方。

你甚至可以利用現有的單元測試框架之一爲好。我正在尋找一個開源框架。 NUnit想到了。潘打算。

無論如何,祝你好運,這是一個有趣的項目。保持我們的發佈,K?

乾杯。基思。

+0

感謝您的輸入!我一直在努力的應用程序在這裏:https://bitbucket.org/jonathanconway/marsrover – Jonathan 2011-05-02 03:42:41

2

我建議使用moles

主要是因爲我更喜歡讓你的設計確定你的接口和類,而不是你的測試

+0

非常有趣的想法。如果我有更多時間,我可以嘗試。這聽起來像一個好方法,因爲我*替換*方法。 – Jonathan 2011-05-02 03:45:57

+0

+1提莫爾斯。我喜歡PEX順便說一句,這至少也是一件很棒的事情,至少可以在後面玩並記住。 – quetzalcoatl 2012-02-27 09:26:51