Изменение настроек приложения в модульных тестах - PullRequest
12 голосов
/ 15 сентября 2010

У меня есть библиотека классов, которую я хочу провести модульное тестирование с использованием среды модульного тестирования Microsoft. Некоторые из классов, которые я хочу протестировать, настраиваются с помощью настроек приложения. Эти настройки определены внутри файла Settings.settings, имеющего область применения и подходящие значения по умолчанию. Когда библиотека используется приложением, эти настройки могут быть переопределены в файле App.Config. Если нет, используются значения по умолчанию. Именно так я и хочу.

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

В моем классе библиотеки я получаю доступ к таким настройкам:

var mySetting1 = Settings.Default.MySetting1;
var mySetting2 = Settings.Default.MySetting2;

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

Ответы [ 2 ]

16 голосов
/ 17 сентября 2010

После разговора с ApplicationSettingsBase и связанными с ним классами я нашел решение моей проблемы.Не особенно красиво, но, безусловно, выполняет свою работу.

Класс сгенерированных настроек кода является внутренним для проекта библиотеки классов и должен быть доступен для проекта модульного теста.Добавьте атрибут [assembly: InternalsVisibleTo("UnitTestAssemblyName")] к AssemblyInfo.cs в проекте библиотеки классов.

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

Settings.Default.Reload();
var dummy = Settings.Default.MySetting1;

Базовые значения теперь существуют и могут быть установлены в каждом методе теста.Не забудьте использовать правильный тип, так как сгенерированный кодом геттер будет выполнять приведение:

Settings.Default.PropertyValues["MyStringSetting1"].PropertyValue = "Foobar";
Settings.Default.PropertyValues["MyDoubleSetting2"].PropertyValue = 3.1416D;
5 голосов
/ 15 сентября 2010

Я бы создал класс-оболочку для класса Settings, а затем передал бы эту оболочку.Затем вы можете легко смоделировать свой класс настроек.

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

Ни то, ни другое не является фантастическим, и это сложно сделать для автоматически генерируемого кода,кажется, это то, что мы застряли, насколько я могу судить, если вы действительно хотите удалить зависимость от файла настроек.

Например, для файла настроек, содержащего строку Application application и int User:

internal sealed partial class Settings : IMySettings {

    /*
     * here be auto-generate code (and dragons!)
     */
}

internal interface IMySettings
{
    string ApplicationSetting
    {
        get;
    }

    string UserSetting
    {
        get;
        set;
    }
}
...