使用模拟TextWriter测试控制台输出 [英] Testing console output using a mock TextWriter

查看:95
本文介绍了使用模拟TextWriter测试控制台输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为输出到控制台的类编写单元测试.为了从此类捕获控制台输出,我决定创建一个模拟TextWriter对象,并将控制台输出重定向到测试类中的对象.

I am trying to write a unit test for a class that outputs to the console. To capture the console output from this class I decided to create a mock TextWriter object and redirect the console output to it within the test class.

[TestMethod]
public void TestMethod()
{
    var outLines = new List<string>();
    var mockWriter = new Mock<TextWriter>();
    mockWriter.Setup(writer => writer.WriteLine(It.IsAny<string>()))
        .Callback<string>(s => outLines.Add(s));
    Console.SetOut(mockWriter.Object);

    // ConsoleLogger is the class being tested
    // It will essentially just print its parameter to the console.
    var logger = new ConsoleLogger();
    logger.Error("foo");

    // Uncommenting this will cause the test to pass
    // Console.WriteLine("foo");

    Assert.AreEqual(1, outLines.Count);
    Assert.AreEqual("foo", outLines[0]);
}

此代码不起作用.但是,如果我在测试中执行Console.WriteLine("foo"),它将可以正常工作.

This code does not work. However if I do a Console.WriteLine("foo") within the test it will work.

在调试测试时,更奇怪的是,由于单元测试不会从Assert异常中输出任何内容,因此Logger类的控制台似乎仍被重定向到任何地方.

Even more strangely when debugging the test the console from the Logger class is still being redirected seemingly to nowhere as the unit test does not output anything asides from the Assert exceptions.

所以基本上我的问题是,为什么从记录器类编写代码时无法运行模拟代码?

So basically my question is why does the mock code not get run when writing from the logger class?

推荐答案

我认为原因一定是您的ConsoleLogger类(您的代码尚未显示?)实际上调用了

I think the reason must be that your ConsoleLogger class (whose code you have not shown?) actually calls another overload or another method.

如果其他成员是virtualabstract,则Moq将覆盖它.由于没有为其他重载提供Setup,因此Moq将为空"实现提供宽松模拟,或者为 strict 模拟抛出异常.尝试更改为:

If that other member is virtual or abstract, Moq will override it. Since you provided no Setup for the other overload, Moq will provide the "empty" implementation with a loose mock, or will throw an exception with a strict mock. Try changing into:

var mockWriter = new Mock<TextWriter>(MockBehavior.Strict);

看看是否有这样的异常有用地发生.我的猜测:这是重载WriteLine(object).使用严格的模拟通常是个好主意.

to see if such an exception helpfully occurs. My guess: It is the overload WriteLine(object). It is often a good idea to use strict mocks.

但是,如果该其他成员不是虚拟成员,则Moq没有机会修改其实现.然后,将使用原始类TextWriter的实现.该实现可能会调用虚拟的其他成员,而您可以Setup该成员.

However, if that other member is non-virtual, Moq has no chance of modifying its implementation. Then the implementation from the original class TextWriter will be used. That implementation might call a different member which is virtual, and you may Setup that.

这篇关于使用模拟TextWriter测试控制台输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆