依赖注入和单元测试——使用静态帮助方法还是私有实例方法

4

从单元测试和依赖注入的角度来看,涉及到帮助方法时,通常采用什么标准?

下面是我的示例情况:

public class GoodiesController : Controller
{
   private IMyContext _context;

   public GoodiesController(IMyContext context)
   {
      _context = context
   }

   public async Task<IAction> GetThoseGoodies()
   { 
       if(YouLikeThemThisWay(Request.Path))
        {
           var result = await _context.GoGetThemThisWay()
        } else { }
    }

我的问题是,如果我可能会有一些类似 YouLikeThemThisWay 的方法,我是更适合将YouLikeThemThisWay(string path)作为某个类的静态帮助器还是私有实例方法呢?
1个回答

4
这真的取决于您的YouLikeThemThisWay(string path)方法所做的事情。我在使用静态方法时遵循以下规则:
  1. 它是否需要非基元依赖项?如果是,请勿使用静态方法。
  2. 它是否会影响应用程序的状态?如果是,请勿使用静态方法。
  3. 它是否扩展了您无法在内部访问的类或类型的功能(例如BCL类或原语)?如果是,请使用静态扩展!
  4. 它是否会影响单元测试-使它们更加困难-如果我无法模拟该例程?如果不是,则将其设置为静态!
  5. 它是否将被多个类型或类使用?如果是,则更适合设置为静态!
  6. 该例程是否执行某种IO操作,例如调用数据库或文件系统?如果是,则不要将其设置为静态。
基本上,易于测试且不影响状态的小助手函数通常可以设置为静态。如果涉及状态,该例程需要您通常注入的依赖项,或者该例程正在进行IO或IPC调用,则不要将其设置为静态。
依赖关系问题的一个警告是,从技术上讲,您可以使用方法注入来处理依赖关系,但我喜欢保持简单。您的方法可能可以设置为静态。
重用在静态中也是一个重要因素。如果该例程仅在一个类中使用,则将其设置为静态可能没有意义。我的大多数静态方法都存在于易于访问任何地方的帮助程序类中。
编辑:请注意,我通常需要五个规则中的大多数或全部来支持静态,以便我甚至考虑使某些内容静态。

我不认为我完全理解第二点。该方法基本上不会调用任何外部资源,它只是在提供的输入上工作。 - rethabile
起初我考虑将其放入“context”中,但问题是我是否真的需要模拟它或只需调用它(即将其从“context”中取出),因此我的问题是“static”还是“private”。 - rethabile
点2意味着你考虑的将方法设为静态是否会影响应用的全局状态,也就是说这个方法是否会改变某个地方的东西,而且这种改变是无法“撤销”的,因此不能连续多次执行该函数并得到相同的结果。静态函数应始终是幂等的 - Carson
如果你想要的函数只是简单地接受一些输入(在这种情况下是一个字符串),并返回一个布尔值而不做其他任何事情,那么它可能是静态函数的一个好选择。 - Carson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接