测试依赖于基本属性的方法

时间:2014-09-25 12:06:14

标签: c# asp.net-mvc-4 unit-testing moq

我有一个继承自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 ... ;
    }
}

2 个答案:

答案 0 :(得分:3)

您可以为Configuration编写适配器,以允许您在单元测试中提供存根配置。我确定有很多不同的实现方式;我喜欢Nathan Gloyn's IConfigurationManager implementation

然后,您将WebConfigurationManagerAdapter注册为用于生产中IConfigurationManager服务的组件,并使用Moq模拟单元测试中的界面。

另外需要注意的是,如果你的ViewModel是一个简单的DTO,我会在单元测试中传递一个真实的实例,因为模拟它没有任何优势。

答案 1 :(得分:1)

您有一个非虚拟属性,它取决于您要模拟的具体方法。

基本上你有三个选择(没有上下文,我建议后两者中的任何一个):

  • 使用隔离框架,例如Microsoft Fakes
  • 修改您的BaseController并将属性更改为虚拟
  • 删除代码中的依赖项(如果您想要遵循SOLID设计,首先应该这样做),例如将其包装在单独的界面中