Как выполнить модульное тестирование метода, который использует статический класс, который, в свою очередь, использует ConfigurationElementCollection?

public class ConfigSection : ConfigurationSection
{        
    public static ConfigSection GetConfigSection()
    {
        return (ConfigSection)System.Configuration.ConfigurationManager.
           GetSection("ConfigSections");
    }

    [System.Configuration.ConfigurationProperty("ConstantsSettings")]
    public ConstantSettingCollection ConstantsSettings
    {
        get
        {
            return (ConstantSettingCollection)this["ConstantsSettings"] ??
               new ConstantSettingCollection();
        }
    }


    public class ConstantSettingCollection : ConfigurationElementCollection
    {   

        public ConstantElements this[object key]
        {
            get
            {
                return base.BaseGet(key) as ConstantElements;
            }
            set
            {
                if (base.BaseGet(key) != null)
                {
                    base.BaseRemove(key);
                }
                this.BaseAdd(this);
            }
        }

        protected override ConfigurationElement CreateNewElement()
        {
            return new ConstantElements();
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((ConstantElements)element).Key;
        }
    }

    public class ConstantElements : ConfigurationElement
    {
        [ConfigurationProperty("key", IsRequired = true)]
        public string Key
        {
            get
            {
                return this["key"] as string;
            }
        }

        [ConfigurationProperty("val", IsRequired = true)]
        public string Constants
        {
            get { return this["value"] as string; }
        }          
    }        
}

public class ConstantHelper
{   
    public static string ConstantForLog
    {
        get
        {
            return ConfigSection.GetConfigSection().ConstantsSettings["ConstantForLog"].Constants;
        }
    }
}

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

public class HomeController
{
    protected string constants;
    public HomeController()
     {
         constants = ConstantHelper.ConstantForLog;
     }
 }

Тестовый код

[TestClass]
public class HomeControllerTester
{
 [TestMethod]
 public void Initialize_Tester()
  {
    //Creating Instance for the HomeController
    HomeController controller = new HomeController();
  }
}

во время отладки найдены настройки приложений не читаются классом ConstantHelper

Решение

Нашел решение, на самом деле оно работает нормально, ошибка сделана в app.config

Еще одна проблема, с которой я столкнулся, - в ConfigSection. Для приложения MVC web.config нет необходимости в namespace type = "type", где, как и в модульном тесте app.config, существует необходимость в namespace type = "type, _namespace"

1 ответ

Решение

Вам придется вводить ConstantHelper в HomeController, Вы можете связать это, а затем ввести его. Из юнит-теста проходят макет объекта IConstantHelper,

ОБНОВИТЬ

Я определил интерфейс для класса ConstantHelper, чтобы дать мне возможность внедрить и смоделировать зависимость.

ConstantHelper.cs

public class ConstantHelper : IConstantHelper
{
    public string ConstantForLog
    {
        get
        {
            return ConfigSection.GetConfigSection().ConstantsSettings["ConstantForLog"].Constants;
        }
    }
}

public interface IConstantHelper
{
    string ConstantForLog { get; }
}

HomeController.cs

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

public class HomeController : Controller
{
    private readonly IConstantHelper _constantHelper;

    public HomeController(IConstantHelper constantHelper)
    {
        _constantHelper = constantHelper;
    }

    public ActionResult Index()
    {
        return View(_constantHelper.ConstantForLog);
    }
}

HomeControllerTest.cs

[TestClass]
public class HomeControllerTest
{
    [TestMethod]
    public void Index_WithDependecySetupCorrectly_ReturnTestString()
    {
        var mockHelper = new Mock<IConstantHelper>();
        const string testDataString = "TestString";
        mockHelper.Setup(z => z.ConstantForLog).Returns(testDataString);

        //Creating Instance for the HomeController
        var controller = new HomeController(mockHelper.Object);

        var result = controller.Index() as ViewResult;

        Assert.IsNotNull(result);
        Assert.AreEqual(testDataString, result.ViewName);
    }
}

Я использую Moq Mocking Framework. Просто установите его с помощью следующей команды в консоли диспетчера пакетов в своем тестовом проекте:

Install-Package Moq

Надеюсь это поможет.

Другие вопросы по тегам