Модульное тестирование файла app.config с помощью NUnit

Когда вы, ребята, тестируете приложение, которое полагается на значения из файла app.config? Как вы проверяете, что эти значения считываются правильно и как ваша программа реагирует на неправильные значения, введенные в файл конфигурации?

Было бы нелепо изменять файл конфигурации для приложения NUnit, но я не могу прочитать значения из app.config, которые хочу протестировать.

Обновлено: я думаю, мне следует уточнить, возможно. Меня не беспокоит, что ConfigurationManager не сможет прочитать значения, но я озабочен тестированием того, как моя программа реагирует на считанные значения.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
60
0
25 018
13
Перейти к ответу Данный вопрос помечен как решенный

Ответы 13

На самом деле, размышляя над этим дальше, я полагаю, что мне нужно сделать, это создать класс ConfigFileReader для использования в моем проекте, а затем подделать его в системе модульного тестирования?

Это обычное дело?

Вы можете читать и писать в файл app.config с классом ConfigurationManager

Аааа, так я могу установить значения в коллекции ConfigurationManager? Я всегда предполагал, что он предназначен только для чтения. Думаю, вот что я получаю, делая предположения: P

Dana 04.10.2008 01:14

Я просто попробовал это, и он отлично работает! Например, ConfigurationManager.AppSettings["SomeKey"] = "MockValue";. Хороший ответ!

Scott Rippey 29.07.2011 22:51

Когда я пробовал, он меняет значение указанного ключа u, но также удаляет значения и все остальные ключи :(

Yasser Shaikh 18.09.2014 10:19

@Yasser: решение Мендельта лучше;)

Steven A. Lowe 19.09.2014 06:07

@ StevenA.Lowe В итоге я использовал красный раствор Pervez Choudhury :)

Yasser Shaikh 19.09.2014 10:21

Вы всегда можете обернуть бит чтения в интерфейсе и получить конкретную реализацию, прочитанную из файла конфигурации. Затем вы должны написать тесты с использованием имитирующих объектов, чтобы увидеть, как программа обрабатывает неверные значения. Лично я бы не стал тестировать эту конкретную реализацию, поскольку это код .NET Framework (и я предполагаю, надеюсь, MS уже протестировала его).

Ответ принят как подходящий

Я обычно изолирую внешние зависимости, такие как чтение файла конфигурации в их собственном классе фасада с очень небольшой функциональностью. В тестах я могу создать фиктивную версию этого класса, которая реализует и использовать ее вместо реального файла конфигурации. Вы можете создать свой собственный мокап или использовать для этого фреймворк, например moq или rhino mocks.

Таким образом, вы можете легко опробовать свой код с разными значениями конфигурации без написания сложных тестов, которые сначала записывают файлы конфигурации xml. Код, который считывает конфигурацию, обычно настолько прост, что требует очень небольшого тестирования.

Страшно видеть, что этот ответ не получил больше голосов, а другие ответы, в которых говорится о добавлении / чтении / редактировании файлов конфигурации, имеют так много точек. Для читателей этот ответ - способ сделать ваши модульные тесты простыми и надежными.

Sébastien Sevrin 08.07.2015 11:11

«Нет проблемы, которую нельзя было бы решить, добавив еще один уровень абстракции». :-)

Iain 26.02.2018 05:27

@lain "За исключением проблемы слишком большого количества уровней абстракции" :)

Igand 25.04.2018 15:26

Самый простой вариант - обернуть методы, считывающие конфигурацию, таким образом, чтобы вы могли подставлять значения во время тестирования. Создайте интерфейс, который вы используете для чтения конфигурации, и реализуйте этот интерфейс, который будет передан в качестве параметра конструктора или установлен для объекта в качестве свойства (как если бы вы использовали инъекцию зависимостей / инверсию управления). В производственной среде передайте реализацию, которая действительно читает из конфигурации; в тестовой среде передайте тестовую реализацию, которая возвращает известное значение.

Если у вас нет возможности рефакторинга кода для обеспечения возможности его тестирования, но все же необходимо его протестировать, Typemock Isolator предоставляет возможность фактически имитировать классы конфигурации .NET Framework, чтобы вы могли просто сказать «в следующий раз я попрошу такое-и- такое значение appSettings, вернуть это известное значение ".

У меня была такая же проблема,

вы можете использовать Nunit-console.exe c: \ path1 \ testdll1.dll c: \ path2 \ testdll2.dll

это работает нормально, даже если обе библиотеки указывают на разные app.configs ex testdll1.dll.config и testdll2.dll.config

если вы хотите использовать конфигурацию проекта Nunit и обернуть эти две библиотеки DLL, у вас не может быть двух конфигураций

у вас должен быть project1.config, если ваш проект Nunit - это project1.nunit в том же месте, что и Project1.nunit.

надеюсь это поможет

Вы можете изменить раздел конфигурации во время выполнения в тестовой настройке. Например:

// setup
System.Configuration.Configuration config = 
     ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
config.Sections.Add("sectionname", new ConfigSectionType());
ConfigSectionType section = (ConfigSectionType)config.GetSection("sectionname");
section.SomeProperty = "value_you_want_to_test_with";
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("sectionname");

// carry out test ...

Вы, конечно, можете настроить свои собственные вспомогательные методы, чтобы сделать это более элегантно.

Однако чтение файла с диска превращает весь набор тестов в интеграционные. Вы больше не участвуете в модульном тестировании, поскольку используется глобальное состояние и внешние зависимости.

sara 12.10.2015 14:17

У меня были похожие проблемы с web.config .... Я нашел интересное решение. Вы можете инкапсулировать функцию чтения конфигурации, например что-то вроде этого:

public class MyClass {

public static Func<string, string> 
     GetConfigValue = s => ConfigurationManager.AppSettings[s];

//...

}

А затем обычно используйте

string connectionString = MyClass.GetConfigValue("myConfigValue");

но в модульном тесте инициализируйте "переопределить" функцию следующим образом:

MyClass.GetConfigValue = s =>  s == "myConfigValue" ? "Hi", "string.Empty";

Подробнее об этом:

http://rogeralsing.com/2009/05/07/the-simplest-form-of-configurable-dependency-injection/

Более элегантное решение - использовать простую инъекцию старых зависимостей в сами настройки конфигурации. IMHO это чище, чем издевательство над классом / оболочкой чтения конфигурации и т. д.

Например, предположим, что классу «Погода» для работы требуется «ServiceUrl» (например, он вызывает веб-службу для получения информации о погоде). Вместо того, чтобы иметь некоторую строку кода, которая активно переходит в файл конфигурации для получения этой настройки (будь то код в классе Weather или в отдельном считывающем устройстве конфигурации, которое можно было бы имитировать в соответствии с некоторыми другими ответами), класс Weather может разрешить параметр, который должен быть введен, либо через параметр конструктора, либо, возможно, через установщик свойств. Таким образом, модульные тесты становятся чрезвычайно простыми и прямыми и даже не требуют имитации.

Затем значение параметра может быть введено с помощью контейнера Inversion of Control (или Dependency Injection), поэтому потребителям класса Weather не нужно явно указывать значение откуда-то, поскольку оно обрабатывается контейнером.

Это сработало для меня:

 public static void BasicSetup()
  {
     ConnectionStringSettings connectionStringSettings = 
          new ConnectionStringSettings();
     connectionStringSettings.Name = "testmasterconnection";
     connectionStringSettings.ConnectionString = 
          "server=localhost;user=some;database=some;port=3306;";
     ConfigurationManager.ConnectionStrings.Clear();
     ConfigurationManager.ConnectionStrings.Add(connectionStringSettings);
  }

Вы можете вызвать метод set ConfigurationManager.AppSettings, чтобы установить значения, необходимые для этого конкретного модульного теста.

[SetUp]
public void SetUp()
{
  ConfigurationManager.AppSettings.Set("SettingKey" , "SettingValue");
  // rest of unit test code follows
}

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

Это был самый простой способ решить эту проблему для моих целей. Мой код только что проверил, был ли ключ с именем Environment TEST или LIVE. Поэтому я просто установил ключ на TEST в начале метода модульного тестирования.

Erik L 19.06.2013 11:59

Ну, у меня была такая же проблема ... Я хотел протестировать проект BL, на который ссылается веб-сайт. но я хотел проверить только BL. Поэтому в событии перед сборкой тестового проекта я копирую файлы app.Config в папку bin \ debug и ссылаюсь на них из app.config ...

System.Configuration.Abstractions - прекрасная вещь, когда дело доходит до тестирования такого рода вещей.

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

Вот сайт NuGet: https://www.nuget.org/packages/System.Configuration.Abstractions/

Я использую это почти во всех своих .NET-проектах.

Другие вопросы по теме