在测试设置和拆卸中重定向 Console.Out

Redirecting Console.Out within test Setup and Teardown

这是 Mark Seemann 接受的答案中 Grabbing the output sent to Console.Out from within a unit test? and the referenced article 的跟进。

我想在测试时使用 Console.Out 和 Console.In 重定向流。 class 中的每个测试都需要使用重定向。

为了保持测试干净,我想在测试设置和拆卸中执行此操作。

这就是我的想法:

private StringWriter _sw;
private StringReader _sr;
[SetUp]
public void SetUp()
{
    _sw = new StringWriter();
    Console.SetOut(_sw);
    _sr = new StringReader("100");
    Console.SetIn(_sr);
}

[TearDown]
public void TearDown()
{
    var standardOut = new StreamWriter(Console.OpenStandardOutput());
    standardOut.AutoFlush = true;
    Console.SetOut(standardOut);
    Console.SetIn(new StreamReader(Console.OpenStandardInput()));
 }

然后我会在测试中使用“_sw.ToString()”来验证写入流的内容。

为此使用设置或拆卸方法是否有任何主要缺点? 这是否类似于使用 using 语句进行重定向? 例如

using (StringWriter sw = new StringWriter())
{
    ...
}

Are there any major drawbacks of using setup or teardown methods for this?

是的,虽然可能无法衡量。

此处描述了SetupTearDown方法,每次测试都会创建两个新的一次性对象,但它们永远不会被丢弃。它们最终会超出范围并在垃圾收集器 运行 时被最终确定,但它可能以不太确定的方式发生。从理论上讲,它会使用比确定性处理更多的内存和处理器指令,但正如 Knuth 40 年前教导我们的那样,我们应该衡量而不是进行过早的优化。

我使用可变状态和 Implicit Setup 以及拆解的主要问题是它不是线程安全的,所以如果您想要 运行 并行进行单元测试,您不能。