Модульное тестирование файла app.config с помощью NUnit - PullRequest
59 голосов
/ 04 октября 2008

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

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

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

Ответы [ 13 ]

44 голосов
/ 04 октября 2008

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

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

31 голосов
/ 01 ноября 2008

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

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

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

24 голосов
/ 22 декабря 2010

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

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

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

16 голосов
/ 04 октября 2008

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

11 голосов
/ 19 мая 2009

У меня были похожие проблемы с 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/

3 голосов
/ 23 сентября 2009

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

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

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

2 голосов
/ 27 марта 2010

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

 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);
  }
1 голос
/ 11 мая 2015

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

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

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

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

1 голос
/ 04 октября 2008

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

0 голосов
/ 13 апреля 2015

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...