嘲笑’System.Console’的行为

是否有一种标准方法可以通过对接口而不是System.Console进行编程来使C#控制台应用程序单元可测试?

例如,使用IConsole界面?

你做过这个,你用过什么样的方法?

您是否公开了应用程序需要写入标准输出的事件?

我认为你使用界面的方法是有效的,我认为我不会利用事件。 假设应用程序不接受命令行参数以外的用户输入,我可能会使用这样的东西来包装Console.Write/Console.WriteLine

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

为了测试,我要么创建一个TestConsoleWriter ,它将所有写入存储到我可以断言的缓冲区中,或者我将创建一个模拟并validation是否使用我期望的参数调用了WriteWriteLine 。 如果你的应用程序要对控制台进行大量写入(比如输出+100 MB左右),那么出于性能原因,使用模拟可能会更好,但除此之外我会说你选择哪种方法更容易使用。

然而,这种方法确实有一些限制。 如果您正在使用任何无法修改的程序集并且它们写入控制台,那么您将无法看到该输出,因为您无法强制这些类使用您的IConsoleWriter 。 另一个问题是WriteWriteLine方法有18个左右的重载,所以你可能会包装很多方法。 要解决这些限制,您可能只想在测试时使用Console.SetOut方法将控制台输出重定向到您自己的TextWriter

就个人而言,我想我会采用SetOut方法。 它只需要在unit testing开始时(或者可能在SetUp方法中)添加一行,并且可以断言写入TextWriter

您希望更改控制台在unit testing中写入的流。 然后你可以放入模拟流或其他任何东西。 在测试控制台上查看Mark Seemann的这篇文章:

http://blogs.msdn.com/b/ploeh/archive/2006/10/21/consoleunittesting.aspx

我昨晚碰巧遇到了这个post: 使用reflection来覆盖C#中的虚方法表 。

@paulo想出了答案: LinFu by Philip Laureano。

Philip Laureano的开发博客上的使用示例:Intercepting Console.WriteLine引导您完成如何拦截对Console.WriteLine方法的调用的示例,并且(在这种情况下)还执行一些额外的操作…… AOP for .NET。 .. 非常吵,恕我直言!

LinFu可能只是门票,因为它没有被截获的东西存在,所以你可以“拦截和修改”在你的上下文调用第三方供应商程序集的行为,但没有任何影响截获的类在该上下文之外的行为……所以LinFu听起来像是一个开始实现“控制台应用程序的通用测试框架”的好地方。

您甚至可以利用现有的unit testing框架之一。 我正在寻找一个开源框架。 NUnit浮现在脑海中。 双关语意图。

祝它好运,这是一个有趣的项目。 让我们发布,K?

干杯。 基思。

我推荐使用痣 。

主要是因为我更喜欢让你的设计决定你的接口和类,而不是你的测试