Тестирование сценариев высокой загрузки с помощью Effort.EF6


Вопрос

Мы используем Effort.EF6 для создания набора тестов для службы ASP.NET Web API 2, работающей против базы данных в памяти, и по большей части это замечательный опыт.

Однако по причинам, не связанным с этим вопросом, нам пришлось отключить ленивую загрузку в EF6 (запустив Configuration.LazyLoadingEnabled = false; в конструкторе контекста db), что означает, что если мы забудем .Include() отношение где-то и позже используйте его, мы получаем NullReferenceExceptions . Нам бы хотелось, чтобы наши тесты ломали эти типы ошибок.

Наша тестовая установка в основном такова:

  1. Создайте соединение db с помощью фабрик подключения Effort. Это уникальный экземпляр подключения (с уникальным ключом, когда мы пытаемся использовать постоянные соединения) для каждого теста.
  2. Создайте контекст db с этим соединением и добавьте данные, которые мы хотим использовать для теста.
  3. Зарегистрируйте переопределение службы в контейнере DI для контекста db.

Проблема в том, что мы не можем понять, как настроить Effort.EF6, чтобы запретить ленивую загрузку, так как кажется, что все, что мы добавили в контекст в нашей тестовой настройке, уже загружено, когда работает тестовый код, и поэтому мы никогда не см. исключения. Мы предполагаем, что это связано с тем, что мы повторно используем экземпляр контекста между установкой теста и фактическим выполнением кода.

Если мы попытаемся переключить третий шаг на следующее:

  1. Зарегистрируйте переопределение службы в контейнере DI для подключения db.
  2. Контейнер DI создает экземпляр контекста db (принимая соединение db как вложенную зависимость)

мы вместо этого получаем пустой контекст db, то есть он не имеет данных, несмотря на то, что мы добавляем несколько точек данных перед запуском теста.

Как мы можем построить и внедрить db-контекст с помощью Effort, который не будет работать, если .Include() отсутствует, но работает, если он есть?

Принятый ответ

Вы также должны деактивировать его в конструкторе для Effort.EF6 - тот, который принимает объект DbConnection .

Я решил это для моего проекта EF Code First:

public class MyDataContext : DbContext, IMyDataContext
{
    /*
    * the ohter stuff like IDbSet<T> etc.
    */


    public MyDataContext() : base("name=MyConnectionString")
    {
        Configure();
    }

    /// <summary>
    /// This constructor is for test usage only!
    /// </summary>
    /// <param name="connection">Test connection for in memory database</param>
    public MyDataContext(DbConnection connection) : base(connection, true)
    {
        Configure();
    }


    /// <summary>
    /// Configures the data context.
    /// </summary>
    private void Configure()
    {
        Configuration.LazyLoadingEnabled = false;
    }
}

Кроме того, в моих тестовых проектах я настраиваю тестовые CSV-файлы. Файлы будут использоваться Effort.EF6 для создания контекста с засеваемыми данными. В моем случае я написал небольшой TestDataManager, который дает возможность посещать определенные таблицы с определенными файлами.

Вот фрагмент кода, как вы могли бы засеять данные с помощью Effort.EF6:

public class MyDataContext : DbContext, IMyDataContext
{
    /*
    * the ohter stuff like IDbSet<T> etc.
    */


    public MyDataContext() : base("name=MyConnectionString")
    {
        Configure();
    }

    /// <summary>
    /// This constructor is for test usage only!
    /// </summary>
    /// <param name="connection">Test connection for in memory database</param>
    public MyDataContext(DbConnection connection) : base(connection, true)
    {
        Configure();
    }


    /// <summary>
    /// Configures the data context.
    /// </summary>
    private void Configure()
    {
        Configuration.LazyLoadingEnabled = false;
    }
}

Возможно, этот пост в блоге тоже может помочь вам.





Лицензировано согласно: CC-BY-SA
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему