c#单元测试(Nunit):控制台应用程序的主要方法

本文关键字:应用程序 方法 控制台 单元测试 Nunit | 更新日期: 2023-09-27 18:10:51

我有一个关于主机应用主方法单元测试的问题,标准签名是

  public static void Main(string[] args)

我希望能够测试,以确保只有1个参数被传入。如果传入的参数超过一个,我希望测试失败。

我不认为我可以模仿MOQ,因为它是一个静态方法。

有人有过这样的经历吗?

有什么想法吗?

谢谢

c#单元测试(Nunit):控制台应用程序的主要方法

在您的场景中没有什么可模仿的。静态Program.Main是一个方法,就像任何其他方法一样,您可以通过调用它来测试它。

static void方法的问题是,您只能验证它是否抛出异常或与输入参数(或最终与其他静态成员)交互。因为在string[]上没有什么可交互的,所以你可以测试前一种情况。

然而,更合理的方法是将Main中包含的所有逻辑委托给单独的组件并对其进行测试。这不仅允许您彻底测试输入参数处理逻辑,而且还将Main简化为或多或少如下所示:

public static void Main(string[] args)
{
    var bootstrapper = new Bootstrapper();
    bootstrapper.Start(args);
}

集成测试

ProgramTest.cs

using NUnit.Framework;
namespace Tests;
public class ConsoleTests
{
    [Test]
    public void ProhibitsMoreThanOneArgument()
    {
        var capturedStdOut = CapturedStdOut(() =>
        {
            RunApp(arguments: new string[] { "argument1", "argument2" });
        });
        Assert.AreEqual("Passing two arguments is not supported.", capturedStdOut );
    }
    void RunApp(string[]? arguments = default)
    {
        var entryPoint = typeof(Program).Assembly.EntryPoint!;
        entryPoint.Invoke(null, new object[] { arguments ?? Array.Empty<string>() });
    }
    string CapturedStdOut(Action callback)
    {
        TextWriter originalStdOut = Console.Out;
        using var newStdOut = new StringWriter();
        Console.SetOut(newStdOut);
        callback.Invoke();
        var capturedOutput = newStdOut.ToString();
        Console.SetOut(originalStdOut);
        return capturedOutput;
    }
}
实施

Program.cs

if (args.Length > 1)
{
    Console.WriteLine("Passing two arguments is not supported.");
}