Skip to content

The Web SDK should default the Program class in top-level statements programs to public so that it's easy to reference from test projects #30274

Open
@DamianEdwards

Description

@DamianEdwards

When writing integration tests for ASP.NET Core apps, it's common to use the WebApplicationFactory<T> class to create and configure a test instance of the application. This class accepts a generic argument, the type of which is used to discover the application entry point in the type's assembly. It is often very common to (and documented as such) to use the application's Program class as the generic argument, e.g:

public class BasicTests : IClassFixture<WebApplicationFactory<Program>>
{
    private readonly WebApplicationFactory<Program> _factory;

    public BasicTests(WebApplicationFactory<Program> factory)
    {
        _factory = factory;
    }

    public async Task Get_HomePage_ReturnSuccessAndCorrectContentType()
    {
        // Arrange
        var client = _factory.CreateClient();
        var path = "/";

        // Act
        var response = await client.GetAsync(path);

        // Assert
        response.EnsureSuccessStatusCode(); // Status Code 200-299
        Assert.Equal("text/html; charset=utf-8", response.Content.Headers.ContentType.ToString());
    }
}

When the ASP.NET Core application uses C# top-level statements in Program.cs however (as is the default in ASP.NET Core project templates since .NET 6), the Program class is internal by default, and thus cannot be accessed by the test project without further configuration, either:

  • Configuring InternalsVisibleTo in the ASP.NET Core project to allow the test project to see its internal types/members
  • Explicitly making the generated Program class public by adding public partial class Program { } to Program.cs (or somewhere else in the project)

While another public class in the ASP.NET Core project could be used as the generic argument to WebApplicationFactory, in some cases with top-level statements and minimal APIs there may not even be public classes in the project.

Proposal

To solve this, we should update the Web SDK to, by default, include a source generator that generates the requisite public partial class Program { } unless the project already includes an explicit non-public Program class declaration. This behavior should be able to be disabled by setting an MSBuild property GenerateImplicitPublicProgram to "false".

@davidfowl

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions