MVC控制器是否需要参数化构造函数来进行模拟?

时间:2014-01-23 20:55:25

标签: .net asp.net-mvc c#-4.0 mocking tdd

如果我有controller这样做:

//MyController

public ActionResult MyMethod(string someString)
{
  object test = new object();
  (new MyClassA()).DoSomething(test);
  return View();
}

我是否需要为此控制器创建constructor,以便我可以将其传递给MyClassA的模拟版本?

//Test

Mock<IMyClassA> a = new Mock<IMyClassA>();
a.Setup(m => m.DoSomething(new object());
MyController controller = new MyController(a.Object);

1 个答案:

答案 0 :(得分:1)

是的,因此,通常通过构造函数将引用传递给您希望在某个控制器中使用的所有服务(类)并将其分配给此控制器的私有字段是一种很好的做法。然后,当调用某个Action时,您不必在此Action的主体内实例化某个类。它还使您能够更轻松地测试/模拟它。

更进一步,你可以考虑使用Inversion of Control(依赖注入)模式,并在控制器的构造函数中传递这些类的接口,而不是传递实际的实现。

所以你的控制器看起来像这样:

public class SomeController : Controller
{
    private readonly ISomeService _someService;

    public SomeController(ISomeService someService)
    {
        _someService = someService; 
    }

    public ActionResult Index()
    {
        return View(_someService.GetSomeModel());
    }
}