2014-09-25 5 views
0

У меня есть класс QuickController, который наследуется от BaseController. Метод в QuickController вызывает свойство на BaseController, которое имеет зависимость от ConfigurationManager.AppSettings.Протестируйте метод с зависимостью от базового свойства

Я хочу модульный тест QuickController, но не могу найти способ избавиться от этой зависимости. Вот мой тест:

[TestMethod] 
public void TestMethod1() 
{ 
    var moqServiceWrapper = new Mock<IServiceWrapper>(); 

    var controller = new QuickController(moqServiceWrapper.Object); 

    //Act 
    var result = controller.Estimator(QuickEstimatorViewModel); 

    //Assert 
    Assert.IsInstanceOfType(result, typeof(ViewResult)); 
} 

QuickController класс

public class QuickController : BaseController 
{ 
    public QuickController(IServiceWrapper service) 
     : base(service) { } 

    public ActionResult Estimator(QuickEstimatorViewModel viewModel) 
    { 
     viewModel.RiskAddressLocation = RiskAddressLocation; 

     .... 

     return View("QuickQuote", viewModel); 
    } 
} 

И свойство BaseController

public RiskAddressLocation RiskAddressLocation 
{ 
    get { return ConfigurationManager.AppSettings["..."] 
          .ToEnum<RiskAddressLocation>(true); } 
} 

Я также пытался вызвать метод на FakeQuickController что унаследовать от QuickController, но может» t переопределяет свойство, это тот, который всегда вызывается в BaseController.

Есть ли что-нибудь, что я могу здесь сделать?

Update

От принятого ответа здесь, что я имел, что VS2013 не нравится

public class BaseController{ 
    public virtual RiskAddressLocation RiskAddressLocation {get{...;} 
} 

public class QuickController : BaseController{} 

public class FakeQuickController : QuickController{ 
    public override RiskAddressLocation RiskAddressLocation 
    { 
     get { return ...} // Doesn't compile (cannot override because 
       //BaseController.RiskAddressLocation' is not a function 
    } 
} 

Это, однако, работает отлично

public class BaseController{ 
    public virtual RiskAddressLocation RiskAddressLocation(){...} 
} 

public class QuickController : BaseController{} 

public class FakeQuickController : QuickController{ 
    public override RiskAddressLocation RiskAddressLocation() 
    { 
     return ... ; 
    } 
} 
+1

Похоже, вы хотите [mock ConfigurationManager] (http://stackoverflow.com/questions/9486087/how-to-mock-configurationmanager-appsettings-with-moq), а не пытаться издеваться над базой? – CodingIntrigue

+0

Достаточно справедливо @RGraham, но как перехватить RiskAddressLocation в базовом классе, чтобы он мог его издеваться? – kooshka

ответ

1

У вас есть не виртуальное свойство, которое зависит от конкретного метода, который вы хотите высмеять.

В основном у вас есть три варианта (не учитывая никакого контекста, я предложил бы одну из двух последних):

  • использовать рамки изоляции, как, например, Microsoft Fakes
  • изменить свой BaseController и изменить свойство виртуального
  • удалить зависимость в коде (который вы должны сделать в первую очередь, если вы хотите следовать SOLID конструкции), например, обертывание его в отдельный интерфейс
+0

Если я делаю RiskAddressLocation виртуальным, я могу только переопределить его из QuickController. Я не могу переопределить его, скажем, из FakeQuickController, который наследуется от QuickController. – kooshka

+1

Это неверно - если вы делаете элемент виртуальным, вы можете переопределить его в любом производном классе, независимо от того, сколько раз было разделено. Чтобы дать вам самый простой пример - вы можете переопределить 'ToString' в любом классе (даже тот, который наследуется от другого класса), даже если исходный метод определен в' System.Object'. – decPL

+0

Вы правы ... и не так;) Видите ли, RiskAddressLocation является свойством, и это не позволяет мне переопределить базу из grand-child. Наконец, я получил значительную ошибку, и он сказал, что это невозможно, потому что это не функция. Поэтому я перешел из свойства в функцию и ... он работает :) Принимая ваш ответ в любом случае. Благодарю. – kooshka

3

Вы можете написать адаптер для Конфигурация, позволяющая обеспечить конфигурацию заглушки в модульных тестах. Я уверен, что для этого существует множество различных реализаций; Мне нравится Nathan Gloyn's IConfigurationManager implementation.

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

Еще одно замечание: если ваш ViewModel - это простой DTO, я бы передал реальный экземпляр в модульном тесте, так как нет никакого смысла издеваться над ним.

Смежные вопросы