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

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

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

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

Ответ 1

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

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

Ответ 2

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

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

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

Ответ 3

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

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

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

Ответ 4

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

Ответ 5

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

public class MyClass {

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

//...

}

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

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

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

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

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

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

Ответ 6

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

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

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

Ответ 7

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

 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);
  }

Ответ 8

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

Ответ 10

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

Это обычная вещь?

Ответ 11

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

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

Ответ 12

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

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

это отлично работает, хотя если обе библиотеки dll указывают на разные app.configs ex testdll1.dll.config и testdll2.dll.config

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

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

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

Ответ 13

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