I am trying to move my integration tests from WebApplicationFactory
to TestServer
in .NET 5. In my existing implementation I can override ConfigureWebHost
and call IWebHostBuilder.ConfigureServices
to replace service implementations with mocks. This runs after the Startup
code, allowing me to remove the production implementation and add the mock.
When trying to achieve the same thing using TestServer
, ConfigureServices
always runs before the Startup
code, no matter in which order I do the configuration, meaning I always end up with both implementations in the services collection and it seems "last one wins", i.e. the prod version of the service always runs.
How can I configure the builder to use my test version?
I am using XUnit, so perhaps am not using it in the right way re IClassFixture
etc.
Here is my code:
public sealed class IntegrationTests : IDisposable
{
private TestServer Server { get; }
private HttpClient Client { get; }
public IntegrationTests()
{
var builder = new WebHostBuilder()
.UseConfiguration(new ConfigurationBuilder().AddJsonFile("appsettings.development.json").Build())
.UseSerilog()
// Changing the order of the following two lines doesn't help
.UseStartup<Startup>()
.ConfigureServices(UseDummyUserRepository);
Server = new TestServer(builder);
Client = Server.CreateClient();
}
private void UseDummyUserRepository(IServiceCollection services)
{
//Following line doesn't work as the service is not yet configured
//services.Remove(services.First(s => s.ServiceType == typeof(IUserRepository)));
services.AddTransient<IUserRepository, DummyUserRepository>();
}
This post contains some more info which might be useful.
From my testing the order of execution in an integration test is as follows.
So the issue comes when you attempt to override a service in IWebHostBuilder.ConfigureServices if that service is actually defined in Startup.ConfigureContainer
I tried using IWebHostBuilder.ConfigureTestContainer but it did not appear to be executed.
How to override DI registration from other container in ASP.NET Core integration test