.net MVC控制器是否需要参数化构造函数进行模拟?
如果我有一个执行此操作的.net MVC控制器是否需要参数化构造函数进行模拟?,.net,asp.net-mvc,c#-4.0,mocking,tdd,.net,Asp.net Mvc,C# 4.0,Mocking,Tdd,如果我有一个执行此操作的控制器: //MyController public ActionResult MyMethod(string someString) { object test = new object(); (new MyClassA()).DoSomething(test); return View(); } 我是否需要为此控制器创建一个构造函数,以便向其传递一个模拟版本的MyClassA //Test Mock<IMyClassA> a = new
控制器
:
//MyController
public ActionResult MyMethod(string someString)
{
object test = new object();
(new MyClassA()).DoSomething(test);
return View();
}
我是否需要为此控制器创建一个构造函数
,以便向其传递一个模拟版本的MyClassA
//Test
Mock<IMyClassA> a = new Mock<IMyClassA>();
a.Setup(m => m.DoSomething(new object());
MyController controller = new MyController(a.Object);
//测试
Mock a=新Mock();
a、 设置(m=>m.DoSomething(新对象());
MyController控制器=新的MyController(a.Object);
是的,因此将引用传递给所有服务(类)通常是一种好的做法您希望通过其构造函数在某个控制器中使用,并将其分配给此控制器的专用字段。然后,在调用某个操作时,您不必在该操作体中实例化某个类。这也使您能够更轻松地对其进行测试/模拟
更进一步,您可以考虑使用控制反转(依赖项注入)模式,并在控制器的构造函数中传递这些类的接口,而不是传递实际的实现
因此,您的控制器可以如下所示:
public class SomeController : Controller
{
private readonly ISomeService _someService;
public SomeController(ISomeService someService)
{
_someService = someService;
}
public ActionResult Index()
{
return View(_someService.GetSomeModel());
}
}
是的,除非你的控制器有一个默认构造函数。所以我需要创建一个额外的构造函数来进行测试?这是一个糟糕的做法吗?有人会说你应该用第二种方法来做(IoC使用构造函数进行依赖注入)无论您是否编写控制器测试,但如果确实编写了控制器测试,则可以确定。看起来您正在使用Moq进行模拟。您可以考虑使用不同的模拟库,例如FakeiTesy(),该库支持轻松发送模拟参数。