MVC控制器对静态服务类的依赖性 - 可测试性问题

时间:2014-08-27 14:27:26

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

我是测试的新手,我正在考虑对维护中的一些遗留代码进行单元测试。控制器围绕静态服务调用构建,以获取数据。我不确定最好的前进路径,但我想要么将静态类重构为实例类,要么深入研究可测试性方法。这段代码片段就是我反复遇到的一个简单例子。提前感谢任何建议。 staticMedServiceHelper是一个静态类,具有使用WCF ChannelFactory等的静态Use方法。顺便说一下,如果你有任何WCF / MVC / Testing的良好学习资源,请告诉我。 再次感谢。

public ActionResult Documents(DocumentsForRequirementViewModel model)
{
        staticMedServiceHelper<IMedService>.Use(proxy =>
        {
            var requirment = proxy.GetRequirementById(model.Id);
            var dtos = (IEnumerable<DocumentDTO>)requirement.GetType().GetProperty(model.PropertyName).GetValue(requirement, null);

            model.Documents = Mapper.Map(dtos, new List<DocumentViewModel>());
        });

        return PartialView(model);
}

1 个答案:

答案 0 :(得分:1)

我打破依赖的提示很简单:对于静态,将它们包装在实例类中。

假设你有一个静态记录器(我在生产代码中真的看到了这一点)

public static class Logger
{
  public static void Log(string message)
  {
    //logging logic here..
  }
}

public ActionResult Documents(DocumentsForRequirementViewModel model)
{
  Logger.Log("GET action on Documents");
  //bla bla
}

在这种情况下,依赖关系在记录器的静态实现上是明确的。

我们可以创建一个新的记录器:

public class LogWrapper
{
  public void Log(string message)
  {
    Logger.Log(message);
  }
}

在我们的代码中使用它:

public ActionResult Documents(DocumentsForRequirementViewModel model)
{
  LogWrapper logger = new LogWrapper();
  loggerr.Log("GET action on Documents");
} 

注意:

这只是一个简单的例子。通常,所有外部依赖项首先是Interfaced,然后对于静态实现,只需创建一个实例包装器。

如果你有更复杂的依赖场景,你可以创建装饰器来帮助你从静态到实例的转换,并将代码委托给静态实现。