Search code examples
c#asp.net-coreintegration-testingmstest

How to replace Middleware in integration tests project


I have startup cs where I register AuthenticationMiddleware like this:

public class Startup
{
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        ...
        AddAuthentication(app);
        app.UseMvcWithDefaultRoute();
        app.UseStaticFiles();
    }

    protected virtual void AddAuthentication(IApplicationBuilder app)
    {
        app.UseAuthentication();
    }
}

and I test it using:

WebApplicationFactory<Startup>().CreateClient();

Question:

I would like to replace app.UseAuthentication(); with app.UseMiddleware<TestingAuthenticationMiddleware>(),

What I've tried:

I thought about inheriting from Startup in my test project:

public class TestStartup : Startup
{
    protected override void AddAuthentication(IApplicationBuilder app)
    {
        app.UseMiddleware<AuthenticatedTestRequestMiddleware>();
    }
}

class TestWebApplicationFactory : WebApplicationFactory<Web.Startup>
{
    protected override IWebHostBuilder CreateWebHostBuilder()
    {
        return WebHost.CreateDefaultBuilder()
            .UseStartup<IntegrationTestProject.TestStartup>();
    }
}

but this does not work, since TestStartup is in another assembly, which has a lot of side effects on WebHost.CreateDefaultBuilder()

I'm getting:

System.ArgumentException: The content root 'C:\Projects\Liero\myproject\tests\IntegrationTests' does not exist. Parameter name: contentRootPath


Solution

  • It seems that WebApplicationFactory should use the real Startup class as the type argument:

    class TestWebApplicationFactory : WebApplicationFactory<Startup>
    {
        protected override IWebHostBuilder CreateWebHostBuilder()
        {
            return WebHost.CreateDefaultBuilder<TestableStartup>(new string[0]);
        }
    }