测试对基属性具有依赖关系的方法
本文关键字:依赖 关系 方法 属性 测试 | 更新日期: 2023-09-27 18:24:18
我有一个从BaseController继承的QuickController类。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); }
}
我还尝试在继承自QuickController的FakeQuickController上调用该方法,但无法覆盖该属性,它是BaseController中始终被调用的属性。
我能在这里做点什么吗?
更新
从公认的答案来看,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 ... ;
}
}
您可以为Configuration编写一个适配器,以便在单元测试中提供存根配置。我相信有很多不同的实现;我喜欢Nathan Gloyn的IConfigurationManager
实现。
然后将WebConfigurationManagerAdapter
注册为IConfigurationManager
服务在生产中使用的组件,并使用Moq模拟单元测试中的接口。
另一件需要注意的事情是,如果你的ViewModel是一个简单的DTO,我会在单元测试中通过一个真实的实例,因为嘲笑它没有好处
您有一个非虚拟属性,它依赖于要模拟的具体方法。
基本上你有三种选择(如果没有上下文,我建议后两种中的任何一种):
- 使用隔离框架,例如Microsoft Fakes
- 修改
BaseController
并将属性更改为虚拟 - 删除代码中的依赖项(如果你想遵循SOLID设计,首先应该这样做),例如将其包装在一个单独的接口中