问题
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