Ошибка загрузки TestServer с TestStartup с InMemoryDatabase (ядро .Net)

Возможно, я что-то упустил, а может, что-то сломалось. Я надеюсь узнать, что здесь происходит.

TL; DR: загрузка TestServer класса с базой данных InMemory дает (No service for type 'Microsoft.Data.Entity.Storage.IRelationalConnection' has been registered). Какие-нибудь подсказки? Более подробная информация ниже:

У меня есть тестовый класс, который использует TestFixture для начальной загрузки:

public AccountControllerTest(TestServerFixture testServerFixture) : base(testServerFixture)
    {
    }

TestServerFixture выглядит так: общедоступный класс TestServerFixture: IDisposable {общедоступный сервер TestServer {get; }

    public HttpClient client { get; }

    public TestServerFixture()
    {
        // Arrange
        var builder = TestServer.CreateBuilder()
            .UseEnvironment("Development")
            .UseStartup<TestPortalStartup>()
            .UseServices(services =>
            {
                // Change the application environment to the mvc project
                var env = new TestApplicationEnvironment();
                env.ApplicationBasePath =
                    Path.GetFullPath(Path.Combine(PlatformServices.Default.Application.ApplicationBasePath, "..", "MY_APP"));
                env.ApplicationName = "MY_APP";
                //SUPER IMPORTANT: Should be the real application name, else you'll get Roslyn Compiler Errors in your views

                services.AddInstance<IApplicationEnvironment>(env);
            });

        server = new TestServer(builder);

        client = server.CreateClient();
    }

    public void Dispose()
    {
        server.Dispose();
        client.Dispose();
    }
}

И, как вы можете видеть, он использует TestPortalStartup, который выглядит следующим образом: общедоступный класс TestPortalStartup: Startup {private Mock accountRegistrationClientMock;

    public TestPortalStartup(IHostingEnvironment env, IApplicationEnvironment appEnv) : base(env, appEnv)
    {
    }

    public override void SetUpDataBaseAndMigrations(IServiceCollection services)
    {
        services
          .AddEntityFramework()
          .AddInMemoryDatabase()
          .AddDbContext<CmsDbContext> (
            options => options.UseInMemoryDatabase()
        );
    }


    public override void AddFrameworkDependencies(IServiceCollection services)
    {
    // ... not relevant
    }

}

Как вы можете видеть в SetUpDataBaseAndMigrations, мы загружаем InMemoryDatabase и DbContext.

Я использовал эту конструкцию раньше для тестирования службы, которая имеет дело с базой данных. (но это изолированно).

Теперь с интеграционным тестом я не могу запустить тест с помощью:

Результат StackTrace: в Microsoft.Extensions.DependencyInjection.ServiceProviderExtensions.GetRequiredService (поставщик IServiceProvider, тип serviceType) в Microsoft.Extensions.DependencyInjection.ServiceProviderExtensions.GetRequiredService [T] (IServiceProviderExtensions.GetRequiredService. TService] (средство доступа IInfrastructure`1) в Microsoft.Data.Entity.RelationalDatabaseFacadeExtensions.GetRelationalConnection (DatabaseFacade databaseFacade) в Microsoft.Data.Entity.RelationalDatabaseFacadeExtensions.GetDbConnection (DatabaseFacade databaseFacadeExtensions.GetDbConnection (DatabaseFacade databaseFacade. , ILoggerFactory loggerFactory) в MY_APP / Startup.cs: строка 175 Сообщение о результате: произошла одна или несколько ошибок. Служба для типа Microsoft.Data.Entity.Storage.IRelationalConnection не зарегистрирована. Следующие параметры конструктора не имеют совпадающих данных фикстур: TestServerFixture testServerFixture

Если вам интересно, что происходит в MY_APP/Startup.cs (строка 175), а именно:

 logger.LogInformation($"Using SQL Connection: {dbContext.Database.GetDbConnection().DataSource}");

Запуск с «нормальной» базой данных (т. Е. Не с базой данных в памяти) ПРОВОДИТ тест.

Значит, похоже, что отсутствуют какие-то зависимости / проводка? У кого-нибудь есть опыт в этом? Подсказки? и Т. Д.


person Stefan Hendriks    schedule 21.04.2016    source источник
comment
Кажется, работает использование Sqlite вместо inMemory. Хотя это не то, что я хотел. Так что вопрос остается открытым.   -  person Stefan Hendriks    schedule 25.04.2016


Ответы (1)


После того, как я разместил этот вопрос на github AspDotNet, я получил ответ, что InMemoryDatabase из EntityFramework сама по себе не предназначена для проведения подобного интеграционного тестирования.

Альтернативой является использование SQLite, но также в режиме памяти.

Поскольку создание всего этого (с нуля до полностью работающих интеграционных тестов) заняло у меня довольно много времени, чтобы разобраться. Я подумал, что я бы изложил все это в своем блоге:

http://www.stefanhendriks.com/2016/04/29/integration-testing-your-dot-net-core-app-with-an-in-memory-database/

person Stefan Hendriks    schedule 29.04.2016
comment
блог обновлен до .net core 1.0 - я вижу, что многие люди приходят из stackoverflow - надеюсь, это будет полезно! - person Stefan Hendriks; 30.08.2016
comment
Было бы здорово, если бы вы отформатировали код в своем сообщении в блоге - person Cubelaster; 01.06.2021
comment
@Cubelaster спасибо, что указали на это, у него было форматирование кода, но оно сломалось. Фиксированный! - person Stefan Hendriks; 02.06.2021