#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 */)))