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

StackOverflow https://stackoverflow.com/questions/168931

  •  05-07-2019
  •  | 
  •  

Вопрос

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

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

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

Это было полезно?

Решение

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

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

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

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

// 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 ...

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

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

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

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

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

Я столкнулся с похожими проблемами с 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. ком / 2009/05/07 /-Простейшие форм-из-конфигурируемой-зависимостей закачки /

Более элегантным решением является использование простого старого внедрения зависимостей в сами параметры конфигурации. ИМХО, это чище, чем издеваться над классом / оболочкой чтения конфигурации и т. Д.

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

Затем значение параметра может быть введено с использованием контейнера Inversion of Control (или Inpension 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);
  }

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

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

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

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

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

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

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

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

Если у вас нет возможности рефакторинга кода для тестируемости, но по-прежнему нужно его тестировать, 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 и обернуть эти две библиотеки, тогда вы не сможете получить две конфигурации

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top