单元测试 - 如何重构对静态类

时间:2017-08-03 16:53:18

标签: c# unit-testing static

我正在尝试将单元测试添加到现有的代码库中,由于网站的构建方式,我几乎陷入了第一道障碍。

为了详细说明,本站点中的每个控制器都继承自一个名为SiteController的基本控制器,该控制器的构造函数使用静态助手类填充一些数据。

例如

 public class HomeController : SiteController
    {
        public ActionResult Index()
        {
          //Do stuff here
        }    
    }

这是基本控制器

public class SiteController
{
    public SiteController()
    {
        viewModel = CategoryHelper.GetAllCategories();
    }
}

静态GetAllCategories帮助方法

 public static class CategoryHelper
    {
       public static IList<string> GetAllCategories()
        {
          //Go off and get the categories from the WCF layer
          return _categories;
        }
    }

我无法模拟静态类,但是如何重构此代码以便我可以使用单元测试来处理它。我们已经在整个站点中使用了DI,我知道这里的理论 - 我应该将这个静态类包装在一个抽象层中,这对于一般的代码来说更好。但这种实用性我不太确定。

这可能是显而易见的,但我的目标是保持网站工作(显然),但也要重写静态类或调用它,以便我可以对它进行单元测试。我刚开始编写单元测试,所以我只是遇到了这些问题,然后才能看到一个绿色标记通过测试!当我知道理论解决方案但却不知道该怎么做才能让它发挥作用时,这是令人沮丧的,而且是双倍的。

1 个答案:

答案 0 :(得分:2)

public class HomeController : SiteController
{
    public HomeController(ICategoryHelper categoryHelper) : base(categoryHelper)
    {
    }

    public ActionResult Index()
    {
        //Do stuff here
    }    
}

public class SiteController
{
    public SiteController(ICategoryHelper categoryHelper)
    {
        viewModel = categoryHelper.GetAllCategories();
    }
}

public class CategoryHelper : ICategoryHelper
{
    public IList<string> GetAllCategories()
    {
        //Go off and get the categories from the WCF layer
        return _categories;
    }
}

public interface ICategoryHelper
{
    IList<string> GetAllCategories();
}

最重要的是对抽象进行编码,而不是具体的类。 CategoryHelper是一个具体的类,你希望你的控制器利用执行工作的东西而不关心它是如何完成的。因此,您的控制器应该在其构造函数中接受一个接口(如果需要,可以将其传递给基本控制器)。

同样,CategoryHelper应该实现一个接口,这基本上是一个合同说&#34;我可以执行ICategoryHelper的工作&#34;。

然后,连接CategoryHelper以满足与依赖项注入器的ICategoryHelper依赖关系。如何执行此操作取决于您使用的特定工具(AutoFac,Ninject,SimpleInjector等)。

注意:如果类别不经常更改,则缓存模式可能会更好。