有製作C#控制檯應用程序的單位可測試通過編程對一個接口,而不是System.Console的標準呢?嘲諷「System.Console行爲
例如,使用IConsole接口?
您是否已經完成了這項操作,並且您使用了哪種方法?
你暴露當你的應用程序需要寫入到標準輸出的事件?
有製作C#控制檯應用程序的單位可測試通過編程對一個接口,而不是System.Console的標準呢?嘲諷「System.Console行爲
例如,使用IConsole接口?
您是否已經完成了這項操作,並且您使用了哪種方法?
你暴露當你的應用程序需要寫入到標準輸出的事件?
我想用一個接口的方法是有效的,而且我不認爲我會利用事件。假設應用程序不接受超過命令行參數的其他用戶輸入,我可能會使用這樣的包裝Console.Write/Console.WriteLine
:
public interface IConsoleWriter
{
void Write(string format, params object[] args);
void WriteLine(string format, params object[] args);
}
爲了測試,我就可以創建一個TestConsoleWriter
,將存儲所有寫入的緩衝區然後我可以斷言,否則我會創建一個模擬並驗證Write
或WriteLine
是否使用我期望的參數進行調用。如果您的應用程序將要大量寫入控制檯(比如說+100 MB左右的輸出),那麼使用模擬可能會更適合性能方面的原因,但除此之外,我會說選擇您認爲的任何一種方法更容易與之合作。
但是,這種方法確實有一些限制。如果您正在使用任何不能修改的程序集並將它們寫入控制檯,那麼您將看不到該輸出,因爲您無法強制這些類使用IConsoleWriter
。另一個問題是Write
和WriteLine
方法有18個左右的重載,所以你可能會包裝很多方法。爲了解決這些限制,您可能只想在測試時使用Console.SetOut
方法將控制檯輸出重定向到您自己的TextWriter
。
就我個人而言,我想我會採取SetOut
的方法。在你的單元測試開始時(或者可能在SetUp
方法中),你只能添加一行,你可以對寫入TextWriter
的內容進行斷言。
我正好在這個線程昨晚行程: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?
乾杯。基思。
感謝您的輸入!我一直在努力的應用程序在這裏:https://bitbucket.org/jonathanconway/marsrover – Jonathan 2011-05-02 03:42:41
您想要更改控制檯在單元測試中寫入的流。然後你可以放入一個模擬流或其他任何東西。檢查測試控制檯這篇文章由馬克西曼:
http://blogs.msdn.com/b/ploeh/archive/2006/10/21/consoleunittesting.aspx
我建議使用moles。
主要是因爲我更喜歡讓你的設計確定你的接口和類,而不是你的測試。
非常有趣的想法。如果我有更多時間,我可以嘗試。這聽起來像一個好方法,因爲我*替換*方法。 – Jonathan 2011-05-02 03:45:57
+1提莫爾斯。我喜歡PEX順便說一句,這至少也是一件很棒的事情,至少可以在後面玩並記住。 – quetzalcoatl 2012-02-27 09:26:51
可能重複[可以用Moq嘲弄嗎?](http://stackoverflow.com/questions/1220454/can-this-be-mocked-with-moq) – Jonathan 2011-05-02 02:05:56