检查 MSTest 单元测试中的输出

发布于 2024-08-22 04:53:24 字数 336 浏览 16 评论 0原文

我想在 MSTest 单元测试中捕获发送到标准输出和标准错误的输出,以便我可以验证它。我之前在显式运行 Process 时捕获过输出,但是有没有办法处理[我猜] MSTest 进程本身?例如:

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

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()
{
    MySnazzyMethod("input", 1, 'c');
    string stdOutFromMySnazzyMethod = /* ??? */;
    Assert.AreEqual("expected output", stdOutFromMySnazzyMethod);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

少女的英雄梦 2024-08-29 04:53:24

我不确定是否有办法获取已运行的进程的输出。不过,您可以做的是稍微重构您的代码,不写入 Console.WriteLine ,而是接受 TextWriter 实例并写入该实例。

在生产中,您只需将 Console.Out 传递给该方法即可。在测试代​​码中,您可以模拟这种类型并提供更准确的测试。例如

[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();
}

生产代码

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

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');
走走停停 2024-08-29 04:53:24

我喜欢 JaredPar 的想法,但我不想通过在 Console.OutConsole.Error 到我拥有的每个帮助器输出方法中。但是,我的输出确实通过单个类,因此我只在其中设置了几个静态字段:

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

我更新了输出处理程序类中的输出方法以使用这些字段。然后,我更新了该项目的 AssemblyInfo.cs 以包括:

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

这样,我可以在测试方法中重写 _stdOut_stdErr,调用要测试的方法(它使用我的输出)处理类),并确认我期望的输出。

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

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);
厌倦 2024-08-29 04:53:24

只需在类初始化中添加几个 TraceListener你的测试课。

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

夜司空 2024-08-29 04:53:24

我将使用 Moles 将调用重定向到 Console 写入测试代码中的 lambda 方法。

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

请参阅本文档第 16 页:摩尔参考手册

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文