MVC controller dependency on static service class — testability concern
我是新来的测试人员,正在研究在维护中对一些遗留代码进行单元测试。控制器是围绕静态服务调用来获取数据的。我不确定前进的最佳路径,但我正在考虑要么将静态类重组为实例类,要么深入研究可测试性方法。这个代码片段只是我一次又一次遇到的一个简单的例子。事先谢谢你的建议。StaticMedServiceHelper是一个静态类,有一个静态使用方法,使用wcf channelFactory等。顺便说一句,如果您有wcf/mvc/testing的良好学习资源,请告诉我。再次感谢。
1 2 3 4 5 6 7 8 9 10 11 12 | 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 2 3 4 5 6 7 8 9 10 11 12 13 | 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 } |
在这种情况下,对记录器的静态实现的依赖性是明确的。
我们可以创建一个新的记录器:
1 2 3 4 5 6 7 | public class LogWrapper { public void Log(string message) { Logger.Log(message); } } |
在我们的代码中使用它:
1 2 3 4 5 | public ActionResult Documents(DocumentsForRequirementViewModel model) { LogWrapper logger = new LogWrapper(); loggerr.Log("GET action on Documents"); } |
注:
这只是一个简单的例子。通常,所有外部依赖项都首先是接口的,然后对于静态实现,只需创建一个实例包装器。
如果您是更复杂的依赖场景,那么您可以创建装饰器来帮助您从静态转换为实例,并将代码委托给静态实现。