I was fiddling with top-level statements as the entry point for a simple console app, since the new .NET 6 template use them as a default.
Yet, as the language specification very clearly states:
Note that the names "Program" and "Main" are used only for illustrations purposes, actual names used by compiler are implementation dependent and neither the type, nor the method can be referenced by name from source code.
So, if I can't reference the implicit Program
class and it's Main()
method, would it be possible to write unit tests to check the execution flow of the top-level statements themselves? If so, how?
Yes. One option (since .NET 6) is to make the tested project's internals visible to the test project for example by adding next property to csproj:
<ItemGroup>
<InternalsVisibleTo Include ="YourTestProjectName"/>
</ItemGroup>
And then the Program
class generated for top-level statement should be visible to the test project and you can run it next way:
var entryPoint = typeof(Program).Assembly.EntryPoint!;
entryPoint.Invoke(null, new object[] { Array.Empty<string>() });
Something like this is used internally to perform integration tests for ASP.NET Core 6 with minimal hosting model.
Note that generated Main
method can return task if you are using await
's in your top-level statement, so you possibly will need to capture the return of entryPoint.Invoke
and test if it is a Task
and await
it.
Another approach is to explicitly declare Program
class as partial (for example at the end of top-level statement and use it in testing project):
// ...
// your top-level statements
public partial class Program { }