Может ли модульный тестовый проект загрузить файл app.config целевого приложения?

151

Я занимаюсь модульным тестированием приложения .NET (.exe), которое использует файл app.config для загрузки свойств конфигурации. Само приложение модульного тестирования не имеет файла app.config.

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

Есть ли способ переопределить это или мне нужно написать сценарий для копирования содержимого целевого app.config в локальный app.config?

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

РЕДАКТИРОВАТЬ: я должен упомянуть, что я использую VS08 Team System для моих модульных тестов.

Джордан Пармер
источник

Ответы:

59

Самый простой способ сделать это - добавить .configфайл в раздел развертывания в модульном тесте.

Для этого откройте .testrunconfigфайл из ваших решений. В разделе Развертывание добавьте выходные .configфайлы из каталога сборки вашего проекта (предположительно bin\Debug).

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

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

Джероми Ирвин
источник
9
Гораздо проще просто добавить поле app.config в тестовый проект - тогда вам вообще не нужно возиться с .testrunconfig.
Роуланд Шоу
13
@Rowland, если вы сделаете это, вы должны сохранить две копии app.config. Я предпочел бы потратить 10 секунд, один раз, используя инструмент .testrunconfig, чем не забывать обновлять app.config в обоих местах.
Джером Ирвин
66
Разве вы не можете просто добавить ссылку без копирования? (Добавить существующий элемент ...)
EFraim
6
Комментарий EFraim должен быть принятым ответом, это намного проще, чем что-либо еще.
reggaeguitar
28
Для Soln EFraim: обязательно используйте «Добавить как ссылку» из командной кнопки. В противном случае вы все равно получите копию. Кроме того, хотя вопрос задан специально для приложения .Net, это не сработает для веб-приложения, поскольку у конфигурации веб-приложения неправильное имя (Web.Config, а не App.Config)
Роб Фон Нессельроде
104

В Visual Studio 2008 я добавил app.configфайл в тестовый проект как существующий элемент и выбрал копию в качестве ссылки, чтобы убедиться, что он не дублируется. Таким образом, у меня есть только одна копия в моем решении. С несколькими тестовыми проектами это очень удобно!

Добавить существующий элемент

Добавить как ссылку

bbodenmiller
источник
7
Идеальный ответ, простой и объективный! +1
Кустодио
2
Это лучшее решение и должно быть отмечено как ответ.
niaher
4
Для добавления существующего элемента «в качестве ссылки» необходимо: «В диалоговом окне« Добавить существующий элемент »найти и выбрать элемент проекта, который вы хотите связать», затем: «В раскрывающемся списке кнопки« Открыть »выберите« Добавить как ссылку ». "
Уриэль
Это отлично сработало для меня. Я пытаюсь придумать ситуацию, когда это не сработает ... И я уже достаточно подумал. Спасибо!
Dudeman3000
53

Используете ли вы Team System Test или NUnit , рекомендуется создать отдельную библиотеку классов для ваших тестов. Простое добавление App.config в ваш тестовый проект автоматически будет скопировано в папку bin при компиляции .

Если ваш код зависит от конкретных тестов конфигурации, самый первый тест, который я напишу, подтверждает, что файл конфигурации доступен ( так что я знаю, что я не сумасшедший ):

<configuration>
   <appSettings>
       <add key="TestValue" value="true" />
   </appSettings>
</configuration>

И тест:

[TestFixture]
public class GeneralFixture
{
     [Test]
     public void VerifyAppDomainHasConfigurationSettings()
     {
          string value = ConfigurationManager.AppSettings["TestValue"];
          Assert.IsFalse(String.IsNullOrEmpty(value), "No App.Config found.");
     }
}

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

public class MyObject
{
     public void Configure(MyConfigurationObject config)
     {
          _enabled = config.Enabled;
     }

     public string Foo()
     {
         if (_enabled)
         {
             return "foo!";
         }
         return String.Empty;
     }

     private bool _enabled;
}

[TestFixture]
public class MyObjectTestFixture
{
     [Test]
     public void CanInitializeWithProperConfig()
     {
         MyConfigurationObject config = new MyConfigurationObject();
         config.Enabled = true;

         MyObject myObj = new MyObject();
         myObj.Configure(config);

         Assert.AreEqual("foo!", myObj.Foo());
     }
}
bryanbcook
источник
2
Я согласен с духом передачи здесь зависимости конфигурации, на это, кажется, ответил Марк Симанн не меньше! здесь: Провал модульных тестов из-за отсутствия файла .config
Shaun
В строке отсутствует «строка: значение строки = ConfigurationManager.AppSettings [» TestValue]; Я попытался это исправить, но мне пришлось бы найти еще 5 символов, чтобы исправить стек, чтобы я мог внести изменения.
Джейн
22

Если у вас есть решение, которое содержит, например, веб-приложение и тестовый проект, вы, вероятно, хотите, чтобы тестовый проект использовал веб-приложение web.config.

Один из способов решить эту проблему - скопировать файл web.config для тестирования проекта и переименовать его в app.config.

Другое и лучшее решение - изменить цепочку сборки и сделать ее автоматической копией файла web.config для проверки выходного каталога проектов. Для этого щелкните правой кнопкой мыши Test Application и выберите свойства. Теперь вы должны увидеть свойства проекта. Нажмите «Build Events», а затем нажмите «Edit Post-build ...». Напишите туда следующую строку:

copy "$(SolutionDir)\WebApplication1\web.config" "$(ProjectDir)$(OutDir)$(TargetFileName).config"

И нажмите ОК. (Обратите внимание, что вам, скорее всего, нужно изменить WebApplication1 в качестве имени проекта, которое вы хотите протестировать). Если у вас неправильный путь к web.config, то копирование завершится неудачно, и вы заметите это во время неудачной сборки.

Редактировать:

Чтобы скопировать из текущего проекта в тестовый проект:

copy "$(ProjectDir)bin\WebProject.dll.config" "$(SolutionDir)WebProject.Tests\bin\Debug\App.Config"
Антти
источник
Действительно хорошее решение. Это помогло мне избежать копирования и дублирования .configфайлов. Спасибо, что поделился! :)
Лениэль Маккаферри
Очень хорошее решение! Большое спасибо.
Вин
Хорошее решение, но что происходит, когда основные web.configимеют ссылки только на внешние .configфайлы в рамках одного проекта. Поскольку путь может указывать только на папки в одном и том же каталоге (что обычно верно), при запуске тестов он не сможет обрабатывать эти внешние файлы. Есть идеи как это решить?
Sugafree
Это сработало для меня: copy "$ (SolutionDir) \ MainProject \ Web.config" "$ (ProjectDir) app.config"
Эндрю
8

Это немного устарело, но я нашел лучшее решение для этого. Я пытался выбрать ответ здесь, но похоже, что .testrunconfig уже устарел.

1. Для модульных тестов Wrap the config is Interface (IConfig)

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

Mock<IConfig> _configMock;
_configMock.Setup(config => config.ConfigKey).Returns("ConfigValue");
var SUT = new SUT(_configMock.Object);

2. Для тестирования интеграции динамически добавьте нужный вам конфиг

Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
if(config.AppSettings.Settings[configName] != null)
{
    config.AppSettings.Settings.Remove(configName);
}
config.AppSettings.Settings.Add(configName, configValue);
config.Save(ConfigurationSaveMode.Modified, true);
ConfigurationManager.RefreshSection("appSettings");
MichaelChan
источник
5

Это очень просто.

  • Щелкните правой кнопкой мыши по вашему тестовому проекту.
  • Добавить -> Существующий элемент
  • Вы можете увидеть маленькую стрелку рядом с кнопкой Добавить
  • Выберите файл конфигурации, нажмите «Добавить как ссылку»
Хари Дас
источник
4

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

Кори Фой
источник
Я использую VS08 Team System для своих юнит-тестов, но спасибо за совет NUnit!
Джордан Пармер
2

Если ваше приложение использует такие настройки, как Asp.net ConnectionString, вам необходимо добавить атрибут HostType в ваш метод, иначе они не будут загружаться, даже если у вас есть файл App.Config.

[TestMethod]
[HostType("ASP.NET")] // will load the ConnectionString from the App.Config file
public void Test() {

}
Zyo
источник
0

Я использую NUnit, и в моем каталоге проектов у меня есть копия моего App.Config, в которой я изменяю некоторую конфигурацию (например, я перенаправляю в тестовую базу данных ...). Вы должны иметь его в том же каталоге тестируемого проекта, и все будет в порядке.

Патрик Дежарден
источник
0

Я не смог заставить ни одно из этих предложений работать с nUnit 2.5.10, поэтому в итоге я использовал функциональность Project -> Edit для nUnit, чтобы указать целевой файл конфигурации (как говорили другие, он должен находиться в той же папке, что и. сам файл nunit). Положительной стороной этого является то, что я могу дать конфигурационному файлу имя Test.config, которое сделает его более понятным, что это такое и почему это так)

Джейн
источник
0

Ваши модульные тесты рассматриваются как среда, в которой выполняется ваш код для его тестирования. Как и в любой нормальной среде, у вас есть, например, постановка / производство. Возможно, вам также понадобится добавить .configфайл для вашего тестового проекта. Обходной путь - создать библиотеку классов и преобразовать ее в тестовый проект, добавив необходимые пакеты NuGet, такие как NUnit и NUnit Adapter. он отлично работает как с Visual Studio Test Runner, так и с Resharper, и у вас есть app.configфайл в тестовом проекте. введите описание изображения здесь

введите описание изображения здесь

введите описание изображения здесь

введите описание изображения здесь

И наконец отладил мой тест и значение из App.config:

введите описание изображения здесь

Бен
источник