Being able to customize the Host configuration in integration tests is useful to avoid calling services that shouldn't run at all during testing. This was easily achievable using the standard Startup
model, overriding the CreateHostBuilder
from the WebApplicationFactory
. I tried many many things using the "Minimal APIs" approach and couldn't figure it out.
A full example of what was possible using the Startup
model, would be something like this:
Program.cs:
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); })
// This is a service that downloads Configuration from the internet, to be used
// as a source for `IConfiguration`, just like any `appsettings.json`.
// I don't want this running during testing
.AddConfigServer();
}
As you can imagine, the AddConfigServer
calls an external web server to download the configuration I want to use in my app startup, but I definitely don't want my integration tests calling this external web server for several reasons: don't want to depend on external services, don't want to hammer my config server with testing requests, don't want my server customizations to be exposed to my tests, etc.
Using the Startup
model, I could easily change this behavior with this:
public class MyWebApplicationFactory : WebApplicationFactory<Program>
{
protected override IHostBuilder CreateHostBuilder() =>
Host.CreateDefaultBuilder()
// No AddConfigServer for my integration tests
.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
}
//... other customizations
}
However, trying this same approach throws an exception on my integration test startup:
System.InvalidOperationException : No application configured. Please specify an application via IWebHostBuilder.UseStartup, IWebHostBuilder.Configure, or specifying the startup assembly via StartupAssemblyKey in the web host configuration.
Since I don't have a Startup
class, I couldn't figure out how to properly do this. In fact, since this is common in all my web projects, I abandoned Minimal APIs altogether for the moment, until I figure out how to properly achieve this without a Startup
class.
PS.: I have all the "partial Program" and "InternalsVisibleTo" in place, as described here.
WebApplicationFactory
as mentioned in that answer, what I need to do is override theHostBuilder
altogether. I don't want to replace or add new services to it, I want to start fresh with no services registered in my tests. – Narcoanalysis