我对在控制台应用程序中进行Main方法的单元测试有疑问。标准签名是:
public static void Main(string[] args)
我希望能够测试以确保只传递了1个参数。如果传递了多个参数,我希望测试失败。
我认为我无法使用MOQ模拟它,因为这是一个静态方法。
有没有人有相关的经验?
有什么想法吗?
谢谢。
我对在控制台应用程序中进行Main方法的单元测试有疑问。标准签名是:
public static void Main(string[] args)
我希望能够测试以确保只传递了1个参数。如果传递了多个参数,我希望测试失败。
我认为我无法使用MOQ模拟它,因为这是一个静态方法。
有没有人有相关的经验?
有什么想法吗?
谢谢。
在您的情况下,没有任何可嘲笑的地方。静态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.");
}
static int Main
,我有时会利用返回信号来创建单元测试。 - Simeon