Не удается получить доступ к информации из файлов конфигурации, когда тесты имеют тип хоста "Moles" - PullRequest
3 голосов
/ 02 февраля 2012

У нас возникают проблемы с доступом к информации в файлах конфигурации .net (например, app.config и web.config) с помощью модульных тестов, когда модульные тесты имеют тип хоста "Moles". Это вызывает довольно много головных болей, поэтому я надеюсь, что у кого-то есть представление о том, что можно сделать.

Мы используем Visual Studio 2010, и я полагаю, что мы пробовали это на компьютере с установленным VS 2010 SP1 и на компьютере без установленного SP1, а также на 32- и 64-разрядных компьютерах.

Я позволил себе свести тест к самым простым терминам. Проблема может быть воссоздана путем составления проекта модульного тестирования, состоящего из следующих двух файлов, и запуска теста после раскомментирования единственной закомментированной строки. Тест работает без типа хоста, но когда вы вводите Moles как тип хоста, в тесте теряется нулевое утверждение. Мы не уверены, почему.

Сначала файл конфигурации App.config:

<?xml version="1.0"?>
<configuration>
  <connectionStrings>
    <add name="Connection" connectionString="Something" />
  </connectionStrings>
</configuration>

Далее, класс теста, содержащий один тест:

namespace TestProject
    {
    using System.Configuration;
    using Microsoft.VisualStudio.TestTools.UnitTesting;

    [TestClass]
    public class UnitTest
        {

        [TestMethod]
        //[HostType("Moles")]
        public void TestMethod()
            {
            var data = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            Assert.IsNotNull(data.ConnectionStrings.ConnectionStrings["Connection"]);
            }

        }

    }

Я был бы признателен, если бы кто-нибудь мог предложить какое-либо понимание.

Большое спасибо,

Ник

Ответы [ 3 ]

1 голос
/ 04 февраля 2012

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

  1. Создайте интерфейс в тестируемом проекте, который включает свойство для каждого параметра конфигурации. Давайте назовем это «ISettings», для справки.

  2. Создать заглушку (класс) в целевой сборке, которая реализует интерфейс. Каждое свойство в заглушке должно содержать только get, который возвращает соответствующий параметр из файла конфигурации. Мы будем называть эту заглушку «SettingsStub». Эта заглушка используется целевой сборкой в ​​производственной среде.

  3. Добавить типизированный аргумент ISettings в конструктор целевого типа (тестируемый класс). Поле в целевом классе должно быть установлено на объект ISettings, переданный в конструктор. Вы можете создать конструктор перегрузки и сохранить конструктор по умолчанию, как того требуют некоторые шаблоны проектирования (MVVM и т. Д.). Конструктор по умолчанию (тот, у которого нет аргументов) может просто создать новый экземпляр SettingsStub для использования в производстве. Перегруженный конструктор всегда должен использоваться тестами!

  4. Создайте заглушку настроек для тестового проекта, который также реализует ISettings. Мы будем называть это TestSettingsStub. Эта заглушка содержит жестко закодированные значения, приемлемые для большинства тестов.

  5. Перестройте целевой и тестовый проекты. Кроты генерируют тип заглушки с именем SISettings.

Используйте конкретный TestSrtyingsStub, когда вам не нужно настраивать какие-либо значения настроек. В качестве альтернативы используйте тип заглушки Miles, когда значения необходимо скорректировать для одного или двух тестов. Назначение типов заглушек Moles состоит в том, чтобы избежать необходимости создавать множество заглушек, содержащих одно или два уникальных изменения.

Типы SettingsStub, TestSettigsStub и SISettings могут использоваться взаимозаменяемо при вызове перегруженного конструктора. Теперь у вас есть полный контроль над тем, какие настройки используются в каждом контексте, без необходимости переключения логики или ручного изменения значений настроек во время тестирования. Код назначения просто получает значения настроек из локального поля, а не напрямую из файла конфигурации. См. Разделы «Инъекция зависимостей и инверсия контроля» (IOC).

Как обычно, ваша рабочая станция разработки не сможет получить доступ к внешним системам зависимостей (база данных и т. Д.) В производственной сети для безопасности!

Удачного кодирования!

1 голос
/ 03 февраля 2012

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

ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = configurationFilePath;
System.Configuration.Configuration configuration =
    ConfigurationManager.OpenMappedExeConfiguration(
        fileMap,
        ConfigurationUserLevel.None);
0 голосов
/ 06 февраля 2012

Я бы согласился, что ответ Майка логически правильный (т.е. вы не отделяете загрузку своей конфигурации от класса - потенциально), практический вопрос заключается в том, что для типов хостов Moles, согласно вашему исходному вопросу, вам нужно Отмените вызовы в систему конфигурации, например,

 MConfigurationManager.AllInstances.OpenExeConfiguration (... finish your moleing here...)

Синтаксис приблизительный - я не могу вспомнить, в конечном итоге вы использовали SConfigurationManager или MConfigurationManager в этом случае.

Где я полностью не согласен с Майком, так это то, что утверждение "... рабочая станция разработки не сможет получить доступ к внешним системам зависимости ..." - это просто ужасный совет. Мы делаем это под названием интеграционные тесты.

Да, вы, как разработчик, должны их создавать. В какой-то момент вы напишите код, касающийся конкретной реализации (например, базы данных, службы поддержки и т. Д.), И если вы не тестируете это взаимодействие, вы в значительной степени ошибаетесь.

...