aks
aks

Reputation: 133

Unable to use custom startup for .NET 8 integration project

I have an ASP.NET Core Web API project which I have been upgrading and is now running on .NET 8.

I am planning to have integration test included in the project with xUnit.

Now since I always had a startup.cs in earlier version, I stick with the plan of keeping the same approach.

I want to use a TestStartup.cs class for my integration test to manage and inject all the external dependencies as mock.

The problem is when I use TestStartup.cs as my startup and test my controller I get 404 for the endpoint.

It works fine when I point to the actual Startup.cs.

Both Startup.cs and TestStartup.cs have the same code, differing only by mock dependency injection.

This is how my program.cs looks like

public static void Main(string[] args)
{
    MyHost.Start<Startup>(args);
}

public static class MyHost
{
    public static void Start<TStartup>(string[] args, ....) where TStartup: class
    {
        CreateWebHostBuilder<TStartup>(args ,......)
            .Build().Run();
    }

    private static IWebHostBuilder CreateWebHostBuilder(string[] args, ...) where TStartup : 
  class => {
        WebHost.CreateDefaultBuilder(args)
               .UseStartup<TStartup>()
               .ConfigureLogging(....)
               .ConfigureAppConfiguration(...);
    }
}

This is how my Startup looks like:

public class Startup
{
    public void ConfigureService(IserviceCollection services)
    {
        // ....
    }

    public void Configure(IApplicationBuidler app, IWebHostEnvironment env)
    {
        // ....
    }
}

My TestStartUp.cs is an exact copy with only few services registered by mock implementation. Consider no change at all.

This is how I have my customWebApplicationFactory setup for my test.

public class CustomApplicationFactory: WebApplicationFactory<TestStartup> // When I replace it with Startup this works
{
    protected override IWebHostBuilder CreateWebHostBuilder()
    {
        return WebHost.VreateDefaultBuilder()
                      .UseStartup<TestStartUp>() // When I replace it with Startup this works
                      .ConfigureLogging()
                      .ConfigureAppConfiguration();
    }
}

And finally, this is my test

public class MyTest
{
    private readonly HttpClient _client;
    private readonly CustomApplicationFactory _factory;

    public MyTest()
    {
        _client = _factory.CreateClient()
    }

    [Fact]
    public async Task MyTestMethod()
    {
        // code for preparing/sending request using _client and some assertion 
        // which works perfectly fine when pointed to Startup.cs but when 
        // pointed to TestStartup.cs gives my 404(the controller method has no 
       // hit.)
    }
}

Upvotes: 1

Views: 120

Answers (1)

dariomrk
dariomrk

Reputation: 71

Given that Startup.cs / TestStartup.cs are not provided I cannot give a definitive answer as to why the calls to the endpoints are returning 404 when you use the TestStartup.

Since you did mention that the endpoints are available when you use Startup, I suggest you do the following. After calling .UseStartup<Startup>() call the method ConfigureTestServices (ms docs here).

Since you also mentioned this:

My TestStartUp.cs is an exact copy with only few services registered by mock implementation. Consider no change at all.

You will be able to do the same using the aforementioned method. It may look something like this:

// ...
.UseStartup<Startup>()
.ConfigureTestServices(services =>
{
    services.AddTransient<IService, MockService>();
});
// ...

Upvotes: 1

Related Questions