有没有办法对 C# 中的顶级语句进行单元测试?

Sil*_*ube 11 c# testing unit-testing toplevel-statement .net-6.0

我正在摆弄顶级语句作为简单控制台应用程序的入口点,因为新的 .NET 6 模板使用它们作为默认值。

然而,正如语言规范非常清楚地指出的那样:

请注意,名称“Program”和“Main”仅用于说明目的,编译器使用的实际名称取决于实现,并且类型和方法都不能通过源代码中的名称引用

那么,如果我无法引用隐式Program类及其Main()方法,是否可以编写单元测试来检查顶级语句本身的执行流程?如果是这样,怎么办?

Gur*_*ron 18

是的。一个选项(自 .NET 6 起)是使测试项目的内部结构对测试项目可见,例如通过向 csproj 添加下一个属性:

<ItemGroup>
  <InternalsVisibleTo Include ="YourTestProjectName"/>
</ItemGroup>
Run Code Online (Sandbox Code Playgroud)

然后Program为顶级语句生成的类应该对测试项目可见,您可以通过以下方式运行它:

var entryPoint = typeof(Program).Assembly.EntryPoint!;
entryPoint.Invoke(null, new object[] { Array.Empty<string>() }); 
Run Code Online (Sandbox Code Playgroud)

类似的东西在内部使用最小托管模型执行ASP.NET Core 6的集成测试。

请注意,如果您在顶级语句中使用's ,则生成的Main方法可以返回任务,因此您可能需要捕获 的返回并测试它是否是 a和it。awaitentryPoint.InvokeTaskawait

另一种方法是将Program类显式声明为部分类(例如在顶级语句末尾并在测试项目中使用它):

// ...
// your top-level statements

public partial class Program { }
Run Code Online (Sandbox Code Playgroud)