Testing console output using a mock TextWriter

廉价感情. 提交于 2019-12-24 14:29:28

问题


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]);
}

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

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?


回答1:


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

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);

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.

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.



来源:https://stackoverflow.com/questions/31615557/testing-console-output-using-a-mock-textwriter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!