2012-05-14 1 views
3

Я много искал и до сих пор не нашел надежного решения для этого. Предположим, что у вас есть методы в вашем приложении. Эти методы используют «System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration» для доступа к некоторым параметрам в web.config. Если вы попытаетесь протестировать эти методы, ваши тесты потерпят неудачу, потому что ваш тестовый проект не имеет web.config.Методы тестирования со ссылкой на Web.Config в .Net C#

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

public class Config 
{ 
    public static String getKeyValue(String keyName) 
    { 
     if (keyName == String.Empty) return String.Empty; 
     String result = ""; 

     System.Configuration.Configuration rootWebConfig1 = 
      System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(null); 
     if (rootWebConfig1.AppSettings.Settings.Count > 0) 
     { 
      System.Configuration.KeyValueConfigurationElement reportEngineKey = 
       rootWebConfig1.AppSettings.Settings[keyName]; 

      if (reportEngineKey != null) 
      { 
       result = reportEngineKey.Value; 

      } 

     } 

     return result; 
    } 
} 

Каждый раз, когда я пытался установить путь для OpenWebConfiguration(), я получил ошибку «Относительный виртуальный путь не позволил»

ответ

2

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

public interface IConfig 
{ 
    string GetSettingValue(string settingName); 
} 

Тогда я могу иметь свой «реальный» реализация:

public sealed class Config : IConfig 
{ 
    public string GetSettingValue(string settingName) 
    { 
     // your code from your getKeyValue() method would go here 
    } 
} 

Тогда мой код, который использует его бы в экземпляре этого (это пример Dependency Inversion Principal) :

public void DoStuff(IConfig configuration) 
{ 
    string someSetting = configuration.GetSettingValue("ThatThingINeed"); 
    // use setting... 
} 

Так что теперь для моего производства кода, я могу позвонить DoStuff и передать экземпляр Config. Когда мне нужно протестировать, я могу использовать насмешливый инструмент (Moq, JustMock, RhinoMocks и т. Д.), Чтобы создать подделку IConfig, которая возвращает известное значение без попадания в фактический файл .config, или вы можете сделать это без насмешливой структуры делая свои собственные макеты (и сохраняя их в вашем тестовом проекте).

public class ConfigMock : IConfig 
{ 
    private Dictionary<string, string> settings; 

    public void SetSettingValue(string settingName, string value) 
    { 
     settings[settingName] = value; 
    } 

    public string GetSettingValue(string settingName) 
    { 
     return settings[settingName]; 
    } 
} 

и

[Test] 
public void SomeExampleTest() 
{ 
    var config = new ConfigMock(); 
    config.SetSettingValue("MySetting", "SomeValue"); 

    var underTest = new MyClass(); 
    underTest.DoStuff(config); 
} 
+0

Также обратите внимание, что это только один из способов сделать это проверяемым. Это далеко не единственный путь. Существуют также издевательские структуры, которые могут издеваться над методами 'static', и вы можете использовать один из них, чтобы издеваться над существующим методом' Config.getKeyValue() ', причем практически никаких изменений кода не происходит. – CodingWithSpike

+0

Я бы добавил, что ответ ниже на kprobst идет рука об руку с этим ответом. Создайте интерфейс, затем используйте библиотеку Moq (или другую фальшивую фреймворк) для создания макетного объекта, который 'ConfigMock' служит в этом ответе. –

+0

Спасибо! Это, кажется, чистый и многоразовый подход. – Reza

0

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