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





На самом деле, размышляя над этим дальше, я полагаю, что мне нужно сделать, это создать класс ConfigFileReader для использования в моем проекте, а затем подделать его в системе модульного тестирования?
Это обычное дело?
Вы можете читать и писать в файл app.config с классом ConfigurationManager
Я просто попробовал это, и он отлично работает! Например, ConfigurationManager.AppSettings["SomeKey"] = "MockValue";. Хороший ответ!
Когда я пробовал, он меняет значение указанного ключа u, но также удаляет значения и все остальные ключи :(
@Yasser: решение Мендельта лучше;)
@ StevenA.Lowe В итоге я использовал красный раствор Pervez Choudhury :)
Вы всегда можете обернуть бит чтения в интерфейсе и получить конкретную реализацию, прочитанную из файла конфигурации. Затем вы должны написать тесты с использованием имитирующих объектов, чтобы увидеть, как программа обрабатывает неверные значения. Лично я бы не стал тестировать эту конкретную реализацию, поскольку это код .NET Framework (и я предполагаю, надеюсь, MS уже протестировала его).
Я обычно изолирую внешние зависимости, такие как чтение файла конфигурации в их собственном классе фасада с очень небольшой функциональностью. В тестах я могу создать фиктивную версию этого класса, которая реализует и использовать ее вместо реального файла конфигурации. Вы можете создать свой собственный мокап или использовать для этого фреймворк, например moq или rhino mocks.
Таким образом, вы можете легко опробовать свой код с разными значениями конфигурации без написания сложных тестов, которые сначала записывают файлы конфигурации xml. Код, который считывает конфигурацию, обычно настолько прост, что требует очень небольшого тестирования.
Страшно видеть, что этот ответ не получил больше голосов, а другие ответы, в которых говорится о добавлении / чтении / редактировании файлов конфигурации, имеют так много точек. Для читателей этот ответ - способ сделать ваши модульные тесты простыми и надежными.
«Нет проблемы, которую нельзя было бы решить, добавив еще один уровень абстракции». :-)
@lain "За исключением проблемы слишком большого количества уровней абстракции" :)
Самый простой вариант - обернуть методы, считывающие конфигурацию, таким образом, чтобы вы могли подставлять значения во время тестирования. Создайте интерфейс, который вы используете для чтения конфигурации, и реализуйте этот интерфейс, который будет передан в качестве параметра конструктора или установлен для объекта в качестве свойства (как если бы вы использовали инъекцию зависимостей / инверсию управления). В производственной среде передайте реализацию, которая действительно читает из конфигурации; в тестовой среде передайте тестовую реализацию, которая возвращает известное значение.
Если у вас нет возможности рефакторинга кода для обеспечения возможности его тестирования, но все же необходимо его протестировать, 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 ...
Вы, конечно, можете настроить свои собственные вспомогательные методы, чтобы сделать это более элегантно.
Однако чтение файла с диска превращает весь набор тестов в интеграционные. Вы больше не участвуете в модульном тестировании, поскольку используется глобальное состояние и внешние зависимости.
У меня были похожие проблемы с 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 в начале метода модульного тестирования.
Ну, у меня была такая же проблема ... Я хотел протестировать проект BL, на который ссылается веб-сайт. но я хотел проверить только BL. Поэтому в событии перед сборкой тестового проекта я копирую файлы app.Config в папку bin \ debug и ссылаюсь на них из app.config ...
System.Configuration.Abstractions - прекрасная вещь, когда дело доходит до тестирования такого рода вещей.
Вот сайт проекта GitHub с хорошими примерами: введите описание ссылки здесь
Вот сайт NuGet: https://www.nuget.org/packages/System.Configuration.Abstractions/
Я использую это почти во всех своих .NET-проектах.
Аааа, так я могу установить значения в коллекции ConfigurationManager? Я всегда предполагал, что он предназначен только для чтения. Думаю, вот что я получаю, делая предположения: P