Переопределение запуска в WebApplicationFactory не отображает конечные точки - PullRequest
0 голосов
/ 19 октября 2019

Я настроил проект xUnit для тестирования реализации Identity Server. Я создал класс TestStartup, который наследует Startup и переопределяет мою реализацию Identity Server для целей тестирования. Проблема в том, что когда я вызываю мой TestStartup, используя свой пользовательский WebApplicationFactory, мои конечные точки не отображаются. Если я вызываю Startup из моего пользовательского WebApplicationFactory, мои конечные точки отображаются.

Startup.cs

protected readonly IConfiguration _configuration;
protected readonly IWebHostEnvironment _webHostEnvironment;

public Startup(IConfiguration configuration, IWebHostEnvironment environment)
{
    _configuration = configuration;
    _webHostEnvironment = environment;
}

public virtual void ConfigureServices(IServiceCollection services)
{
    ///code goes here
    ConfigureIdentityServices(services);            
}

/// <summary>
/// Split into its own method so we can override for testing
/// </summary>
/// <param name="services"></param>
public virtual void ConfigureIdentityServices(IServiceCollection services)
{
   ///code goes here
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public virtual void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseIdentityServer();
    app.UseRouting();

    //app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

TestStartup.cs

public TestStartup(IConfiguration configuration, IWebHostEnvironment environment) : base(configuration, environment)
{

}

public override void ConfigureServices(IServiceCollection services)
{
    base.ConfigureServices(services);
}

/// <summary>
/// In memory identity database implementation for testing
/// </summary>
/// <param name="services"></param>
public override void ConfigureIdentityServices(IServiceCollection services)
{
    //test implementation
}

public override void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    base.Configure(app, env);          
}

Пользовательский WebApplicationFactory

public class ApplicationFactory<TStartup> : WebApplicationFactory<TStartup> where TStartup : class
{
    protected override IWebHostBuilder CreateWebHostBuilder()
    {
        return WebHost.CreateDefaultBuilder(null).UseEnvironment("Development")
                    .UseStartup<TStartup>();
    }
}

Класс тестирования контроллера

public class UserControllerTests : IClassFixture<ApplicationFactory<Startup>>
{
    private readonly ApplicationFactory<Startup> _factory;

    public UserControllerTests(ApplicationFactory<Startup> factory)
    {
        _factory = factory;
    }

    [Fact]
    public async Task Get_Users()
    {
        var client = _factory.CreateClient();

        var result = await client.GetAsync("/user/users");
        result.StatusCode.Should().Be(HttpStatusCode.OK);
    }

}

Когда я запускаю тест контроллера, при вводе TestStartup вместо Startup я не получаю никаких конечных точек, возвращаемых из конечной точкимаршрутизации, хотя я вызываю метод base.Configure(app,env) из моего TestStartup класса.

1 Ответ

2 голосов
/ 23 октября 2019

У меня точно такая же проблема. Использование запуска подкласса в моем пользовательском подклассе WebApplicationFactory не приводит к регистрации конечных точек, тогда как UseStartup регистрирует их. Странно то, что у меня есть другой проект API (без идентификатора), в котором при запуске подкласса фактически регистрируются конечные точки. Пытался закомментировать все при запуске, кроме services.AddControllers и app.UseRouting / app.UseEndpoints в проекте Identity, и он все еще не работает.

Редактировать: найдено решение. Очевидно, services.AddControllers регистрирует только маршруты в исполняемой сборке, которая в сценарии подкласса интеграционного тестирования является тестовой сборкой. Добавляя необходимые контроллеры в качестве частей приложения, система маршрутизации подбирает маршруты:

services.AddControllers()
    .AddApplicationPart(typeof(<controllername>).Assembly);

все будет работать.

...