1

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

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

最近,我一直在使用一个由于处理标准错误输出的错误而引发错误的库。(请参阅LibTiff.NET ReadDirectory is given System.ObjectDisposedException Only during Unit Tests)。

这是他们的代码相对的样子:

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

基本上,在不运行单元测试时,即使专门处理标准输出也不处理,但在运行单元测试时,是允许的。

谁能解释为什么标准输出仅在单元测试的上下文中是一次性的?

4

2 回答 2

3

在已处置的对象上调用方法将抛出ObjectDisposedException. 例如:

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

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

如果您仔细阅读 BCL 源代码,您会看到Console要么使用StreamWriter(真正的同步流编写器)连接到“真实”流(例如控制台错误流),要么使用StreamWriter.Null.

“真实”StreamWriter以一种特殊的方式构造,因此它是不可关闭的。这意味着即使您关闭它(或处置它),它也会继续按预期运行。

因此,如果您有一个“真正的”控制台流,您可以Console.Error在不关闭基础流的情况下关闭任意次数。你也不会得到任何ObjectDisposedException

如果没有附加到Console.Error关闭的“真实”流,则将关闭不表现出特殊不可关闭行为StreamWriter的底层流(在这种情况下),如果您尝试使用后者,您将获得一个.Stream.NullStreamWriterObjectDisposedException

底线是,ObjectDisposedException如果您在没有真正控制台流的应用程序中过早关闭控制台流编写器,您可以获得一个。

上述信息也适用于Console.Out.

于 2012-09-05T16:37:08.697 回答
2

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

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

于 2012-09-05T16:09:09.137 回答