嘲笑'System.Console'的行为

Jon*_*han 16 c# console unit-testing interface inversion-of-control

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

例如,使用IConsole界面?

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

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

rsb*_*rro 16

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

public interface IConsoleWriter
{
    void Write(string format, params object[] args);
    void WriteLine(string format, params object[] args);
}
Run Code Online (Sandbox Code Playgroud)

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

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

就个人而言,我想我会采取这种SetOut方法.它只是你必须在单元测试开始时(或者可能在SetUp方法中)添加一行,你可以断言写入的内容TextWriter.

  • 我没想到`SetOut`方法.整齐. (2认同)

xof*_*ofz 9

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

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