How to mock dependencies in Integration tests. After upgrade from .NET 3.1 tests started failing

Viewed 34

Bit of context: I had working integration tests in .NET 3.1 upon upgrading them into 6.0 they started failing. It turns out that Startup is called twice. More about root of problem I found here https://github.com/dotnet/aspnetcore/issues/26487#issuecomment-731136043 In my case this means that execution is done one with original Startup and the other time with TestStartup. This causes problem because in Startup I have registration which I want to avoid. Like Hangfire or Datadog but they are created upon registration, so I cannot "delete" them from existance once Startup have run

Previously under NET 3.1 this code worked just fine (as it was calling only TestStartup)

My code:

public abstract class TestFixture : IClassFixture<WebApplicationFactory<Startup>>
{
    private readonly WebApplicationFactory<Startup> _factory;

    protected TestFixture(WebApplicationFactory<Startup> factory)
    {
        _factory = factory;
    }

    protected HttpClient CreateClient(Action<IServiceCollection> customConfiguration = null)
    {
        var projectDir = Directory.GetCurrentDirectory();
        var configPath = Path.Combine(projectDir, "appsettings.json");

        return _factory
            .WithWebHostBuilder(builder =>
            {
                builder.UseStartup<TestStartup>();
                builder.ConfigureTestServices(services =>
                {
                    services
                        .AddAuthentication(TestAuthHandler.SchemeName)
                        .AddScheme<AuthenticationSchemeOptions, TestAuthHandler>(
                            TestAuthHandler.SchemeName, options => { });

                    services.AddMvc().AddApplicationPart(typeof(Startup).Assembly);

                    customConfiguration?.Invoke(services);
                });

                builder.ConfigureAppConfiguration((context, conf) =>
                {
                    conf.AddJsonFile(configPath);
                });

            })
            .CreateClient(new WebApplicationFactoryClientOptions
            {
                AllowAutoRedirect = false,
            });
    }
}
public class TestStartup : Startup
{
    public TestStartup(IConfiguration configuration, IWebHostEnvironment environment) : base(configuration, environment)
    {
    }

    protected override void ConfigureDatadog() { }

    protected override void ConfigureHangfire(IApplicationBuilder app, IServiceProvider serviceProvider) { }

    protected override void AddHangfireServices(IServiceCollection services) { }
}

public class Startup
{
    private readonly IWebHostEnvironment _environment;
    private readonly WebServiceSettings _settings;

    private MonitoringEvents _monitoringEvents;

    public Startup(IConfiguration configuration, IWebHostEnvironment environment)
    {
        _environment = environment;
        _settings = configuration.Get<WebServiceSettings>();
    }

    public void ConfigureServices(IServiceCollection services)
    {
        ConfigureDatadog();
        AddHangfireServices(services);
        ...
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment environment, IServiceProvider serviceProvider)
    {
        ConfigureHangfire(app, serviceProvider);
        ...
    }

    protected virtual void AddHangfireServices(IServiceCollection services) => services.AddHangfire(_settings.MySqlSettings);

    protected virtual void ConfigureHangfire(IApplicationBuilder app, IServiceProvider serviceProvider) => app.UseHangfire(serviceProvider);

    protected virtual void ConfigureDatadog() => DogStatsd.Configure(new StatsdConfig { ... });
}

The only thing that I came up to resolve this was to removed TestStartup and use real 3rd party services, but that's not desired solution

Question: How to make integration tests working in NET 6.0 with the same scope? This means, that hangfire nor Datadog won't be registered / running when tests are running

Any solution is more than welcomed, it does not have to be with CustomStartup.

0 Answers
Related