.NET - 为什么在单元测试期间只允许处理标准输出?

时间:2012-09-05 15:57:02

标签: .net unit-testing disposable dispose

首先,我想指出我并不是真的想要处理标准输出......我只是想知道为什么我会看到所描述的行为。我没有写下描述的坏代码。

我使用.NET 4进行单元测试,使用.NET 3.5进行测试。我正在使用MSTest for .NET 4作为我的测试框架。

最近我一直在使用一个由于处理标准错误输出而导致错误的库。 (见LibTiff.NET ReadDirectory is giving System.ObjectDisposedException Only During Unit Tests)。

这与他们的代码相似:

using (TextWriter stderr = Console.Error)
{
    ...
}

基本上,当没有运行单元测试时,即使有人特别处理标准输出,也不会处理标准输出,但是在运行单元测试时,它是允许的。

任何人都可以解释为什么标准输出只有在单元测试环境中这样做时才是一次性的吗?

2 个答案:

答案 0 :(得分:3)

调用已处置对象上的方法将抛出ObjectDisposedException。 E.g:

var textWriter = Console.Error;
textWriter.Dispose();
textWriter.WriteLine("Test");

最后一行应抛出异常。除了它并不总是这样。

如果您仔细阅读BCL源代码,您可以看到Console使用StreamWriter(实际上是一个同步的流编写器),它连接到" real"流(例如控制台错误流)或StreamWriter.Null无法使用。

"真实" StreamWriter以特殊方式构造,因此不可关闭。这意味着即使你关闭它(或处理它)它只是继续按预期运行。

所以如果你有一个真实的"控制台流您可以根据需要关闭Console.Error,而无需关闭基础流。你也不会得到任何ObjectDisposedException

如果没有"真实"附加到Console.Error StreamWriter的流将关闭基础流(在本例中为Stream.Null),该流不会显示特殊的非关闭行为,如果您尝试使用StreamWriter以后您将获得ObjectDisposedException

最重要的是,如果您在没有真正的控制台流的应用程序中过早关闭控制台流编写器,则可以获得ObjectDisposedException

以上信息也适用于Console.Out

答案 1 :(得分:2)

问题可能是由于MSTest使用标准输出流。除了将时序写入流之外,当您运行测试时,标准输出实际存储并在测试结果中可用。通过处理标准输出流,您可能会干扰测试框架的操作本身。

话虽这么说,这是一个错误 - 所以你的测试向你展示了你不应该做的事情......幸运的是,图书馆已经纠正了这个错误,所以你应该在将来做得好