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

#c# #unit-testing #configuration #startup

#c# #модульное тестирование #конфигурация #запуск

Вопрос:

В нашем проекте есть класс с кучей статических полей, который используется для хранения значений настроек в памяти:

 public class MyConfigurationSettings
{
    public static string MySettingId { get; set; }
    
    public string MySettingProcessIdentifier
    {
        get { return MySettingId; }

        set { MySettingId = value; }
    }
}
  

Я не уверен, почему это так — это потеряно в тумане времени. Этот объект заполняется из файла настроек при запуске.

 var defaultConfiguration = new MyConfigurationSettings();
configuration.GetSection("MyConfiguration").Bind(defaultConfiguration);
  

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

 TypeId = MyConfigurationSettings.MySettingId
  

Но значение всегда пустое (или равно нулю для int), и большинству тестов необходимо проверить, какое значение параметра использует код.

Я взглянул на использование ConfigurationBuilder, но, похоже, единственным полезным вариантом была загрузка файла json, что на самом деле не подходит для модульного теста, и я не уверен, как его привязать.

Как я могу заполнить этот объект для модульного теста?

Комментарии:

1. Почему бы не использовать шаблон options и inject IOptions<T> , а затем не издеваться над своим SUT? Или даже упорядочить значение в начале теста

Ответ №1:

Когда ваш проект запускается, где-то должен быть определен root, который сообщает приложению, где искать appsettings.json (я предполагаю, что вы используете его, если вы говорите о конфигурации). Например.:

 var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
  

Когда вы запускаете тесты, ваш каталог выполнения отличается, и файл не загружается.
Итак, вы можете:

  • установите значения в конструкторе теста (это статический объект с геттерами и сеттером)
  • укажите на нужный файл json-файл, когда начнется ваш тестовый проект, путь будет другим
  • используйте, как предложено в комментариях, и то, что я лично считаю хорошим рефакторингом, путь с DI и IOptions. В этом случае вы можете просто ввести нужные настройки в тестируемый класс.

Вы регистрируете свои настройки при запуске:

 services.Configure<MySettings>(this.Configuration.GetSection("MySettings"));
  

В вашем классе в конструкторе используйте DI:

 public class MyClass{
 public MyClass(IOptions<MySettings> settings) { ... }
}
  

В вашем тесте:

 new MyClass(Options.Create<MySettings>(new MySettings(/* test settings here */)))