2014-08-27 52 views
1

我是测试新手,正在测试维护中一些遗留代码的单元测试。控制器是围绕静态服务调用来获取数据的。我不确定最佳路径,但是我正在考虑将静态类重构为实例类,或者深入研究可测试性方法。这个代码片段是我反复反复思考的简单例子。提前感谢您的任何建议。 staticMedServiceHelper是一个使用WCF ChannelFactory等静态类的静态类。顺便说一句,如果你有任何良好的WCF/MVC /测试学习资源,请让我知道。 再次感谢。MVC控制器依赖于静态服务类 - 可测试性问题

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); 
} 
+0

我不明白'wcf'在这里涉及到哪里;也许有一些误解? – Codor 2014-08-27 14:37:50

+0

我会投票替换它。抛开静态课,这件事要求你对任何你想要的东西都进行反思,这是一个巨大的明显的警告信号,它首先是设计不好的。 – 2014-08-27 14:43:27

+0

staticMedServiceHelper 是利用ChannelFacotry WCF的静态类。也许这些信息不相关。我的主要问题是关于控制器方法的可测试性。谢谢。 – Jon 2014-08-27 14:44:11

回答

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接口,然后为静态实现创建一个实例包装。

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

+0

谢谢亚历克斯。我希望我能投票回答,但我的名声太小。非常感谢。 – Jon 2014-08-27 14:54:50

+0

@Jon不用担心,希望这有助于 – 2014-08-27 14:57:45

+0

但是请注意,只要您在正在测试的类中实例化Logger,就无法获得任何可测试性。如果您需要任何可测试性,您需要从外部设置记录器,最好使用构造函数参数(和依赖注入)。 – erikkallen 2014-08-27 15:06:41