开发者

check output in MSTest unit test

开发者 https://www.devze.com 2022-12-20 13:43 出处:网络
I want to capture output sent to standard out and standard error within an MSTest unit test so that I can verify it.I\'ve captured output before when explicitly running a Process, but is there a way t

I want to capture output sent to standard out and standard error within an MSTest unit test so that I can verify it. I've captured output before when explicitly running a Process, but is there a way to do with [I guess] the MSTest process itself? For example:

[TestMethod]
public void OutputTest()
{
    开发者_JS百科MySnazzyMethod("input", 1, 'c');
    string stdOutFromMySnazzyMethod = /* ??? */;
    Assert.AreEqual("expected output", stdOutFromMySnazzyMethod);
}


I'm not sure there is a way to grab the output of an already running Process. What you could do though is refactor your code slightly to not write to Console.WriteLine but instead take in a TextWriter instance and write to that.

In production you can then just pass Console.Out to the method. In test code you could mock this type and provide much more accurate testing. For example

[TestMethod]
public void OutputTest()
{
    var writer = new Mock<TextWriter>(MockBehavior.Strict);
    writer.Setup(x => x.WriteLine("expected output")).Verifiable();
    MySnazzyMethod(writer.Object, "input", 1, 'c');
    writer.Verify();
}

Production Code

MySnazzyMethod(Console.Out, "input", 1, 'c');


I liked JaredPar's idea but I didn't want to pass in Console.Out and Console.Error to every helper output method I had. However, my output does go through a single class, so I just set a couple static fields in it:

internal static TextWriter _stdOut = Console.Out;
internal static TextWriter _stdErr = Console.Error;

I updated my output methods in the output handler class to make use of these fields. I then updated that project's AssemblyInfo.cs to include:

[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("MyTestProject")]

This way, I can override _stdOut and _stdErr in my test methods, call my method to be tested (which uses my output handling class), and confirm the output I expected.

OutputHandler._stdOut = new StringWriter();
MySnazzyMethod("input", 1, 'c');
OutputHandler._stdOut.Flush();
string expected = "expected output";
string stdout = OutputHandler._stdOut.ToString().Trim(new[] { '\r', '\n' });
Assert.IsFalse(string.IsNullOrEmpty(stdout));
Assert.AreEqual(expected, stdout);


Just add a couple TraceListener in the class initialize of your test classes.


I'd use Moles to redirect the call to Console writes to a lambda method inside your test code.

string result = ""; 
System.Moles.MConsole.WriteLineString = (s) =>
  { result = s; }; 
Assert.IsTrue(result == "The string I want", 
     "Failed to write to console correctly"); 

See page 16 in this document: Moles Reference Manual.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号