Лучший способ внедрить SeedData в пользовательский WebApplicationFactory

Есть какой-то метод безумия. Как правило, если браузер может интерпретировать дату как ISO-8601, он будет. «2005-07-08» попадает в этот лагерь, и поэтому он анализируется как UTC. «8 июля 2005» не может, и поэтому он анализируется по местному времени.

Подробнее см. JavaScript и даты, What Mess! .

0
задан IbrarMumtaz 15 January 2019 в 15:29
поделиться

2 ответа

Вот где я собирался:

Исправленная фабрика:

public class GenericWebApplicationFactory<TStartup, TContext, TSeed>
    : WebApplicationFactory<TStartup>
    where TStartup : class
    where TContext : DbContext
    where TSeed : class, ISeedDataClass
{
    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        base.ConfigureWebHost(builder);
        builder.UseEnvironment("Development");
        builder.ConfigureServices(services =>
        {
            var serviceProvider = new ServiceCollection()
                .AddEntityFrameworkInMemoryDatabase()
                .BuildServiceProvider();

            services.AddSingleton<ISeedDataClass,TSeed >();

            services.AddDbContextPool<TContext>(options =>
            {
                options.UseInMemoryDatabase("InMemoryDbForTesting");
                options.UseInternalServiceProvider(serviceProvider);
                options.EnableSensitiveDataLogging();
            });

            var sp = services.BuildServiceProvider();
            using (var scope = sp.CreateScope())
            {
                var scopedServices = scope.ServiceProvider;
                var db = scopedServices.GetRequiredService<TContext>();
                var logger = scopedServices.GetRequiredService<ILogger<GenericWebApplicationFactory<TStartup, TContext, TSeed>>>();

                var seeder = scopedServices.GetRequiredService<ISeedDataClass>();

                db.Database.EnsureCreated();

                try
                {
                    seeder.InitializeDbForTests();
                }
                catch (Exception ex)
                {
                    logger.LogError(ex, $"An error occurred seeding the database with test messages. Error: {ex.Message}");
                }
            }
        });
    }
}

Исправленная польза:

    _client = new GenericWebApplicationFactory<Startup, GatewayContext, SeedDataClass>().CreateClient();

С примером класса семян:

public interface ISeedDataClass
{
    void InitializeDbForTests();
}

public class SeedDataClass : ISeedDataClass
{
    private readonly GatewayContext _db;

    public SeedDataClass(GatewayContext db)
    {
        _db = db;
    }

    public void InitializeDbForTests()
    {
        _db.Users.AddRange(
            // add some users here
        );

        _db.SaveChanges(true);
    }
}

Теперь я могу заполнить базу данных в памяти, как я считаю нужным, для каждого проекта, где он используется, и теперь мой GenericWebApplicationFactory может быть помещен в вспомогательный пакет lib / nuget, который будет повторно использоваться в других проектах .

0
ответ дан IbrarMumtaz 15 January 2019 в 15:29
поделиться

Если вы просто пытаетесь адаптировать подобный конструктор к прежней реализации вашего CustomWebApplicationFactory<TStartup> класса

_client = new CustomWebApplicationFactory<Startup>(new SeedDataClass()).CreateClient();

, то ваш новый конструктор будет выглядеть так:

public class CustomWebApplicationFactory<TStartup, TContext> : WebApplicationFactory<TStartup> 
    where TStartup : class 
    where TContext : DbContext
{
    private readonly SeedDataClass _seed;

    public CustomWebApplicationFactory(SeedDataClass seed)
    {
        if (seed == null) throw new ArgumentNullException(nameof(seed));

        _seed = seed;
    }
}

а затем обновить ваш вызов конструктора, как показано ниже

new CustomWebApplicationFactory<Startup, YourDbContext>(new SeedDataClass()).CreateClient();
0
ответ дан Svek 15 January 2019 в 15:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: