C# 无法使用Moq在ASP.NET MVC控制器中模拟方法调用
我的ASP.NET MVC应用程序中的“UserController”中有以下代码:C# 无法使用Moq在ASP.NET MVC控制器中模拟方法调用,c#,unit-testing,asp.net-mvc-2,moq,C#,Unit Testing,Asp.net Mvc 2,Moq,我的ASP.NET MVC应用程序中的“UserController”中有以下代码: public class UserController : Controller { public ActionResult Index() { return RedirectToAction("List"); } public ActionResult List() { IUserRepository repo = new UserRe
public class UserController : Controller
{
public ActionResult Index()
{
return RedirectToAction("List");
}
public ActionResult List()
{
IUserRepository repo = new UserRepository();
IQueryable<Business.Entities.User> users = repo.GetAll();
return View("List", users);
}
}
private readonly IUserRepository _repo;
public UserController(IUserRepository repo)
{
_repo = repo;
}
public UserController(): this(new UserRepository())
{
}
公共类UserController:Controller
{
公共行动结果索引()
{
返回重定向到操作(“列表”);
}
公共行动结果列表()
{
IUserRepository repo=新用户存储库();
IQueryable users=repo.GetAll();
返回视图(“列表”,用户);
}
}
使用Moq,我想模拟数据库调用“repo.GetAll()”。以下是我的测试资料:
[Test]
public void List()
{
Mock<IUserRepository> mockRepo = new Mock<IUserRepository>();
mockRepo.Setup(ur => ur.GetAll()).Returns(MockedGetAll());
var v = mockRepo.Object.GetAll();
var controller = new UserController();
var result = controller.List() as ViewResult;
var model = result.ViewData.Model as IQueryable<User>;
Assert.AreEqual("List", result.ViewName);
Assert.IsNotNull(model);
Assert.Greater(model.Count(), 0);
}
[测试]
公众作废清单()
{
Mock mockRepo=新Mock();
mockRepo.Setup(ur=>ur.GetAll()).Returns(MockedGetAll());
var v=mockRepo.Object.GetAll();
var controller=new UserController();
var result=controller.List()作为ViewResult;
var model=result.ViewData.model作为IQueryable;
Assert.AreEqual(“列表”,result.ViewName);
IsNotNull(模型);
Assert.Greater(model.Count(),0);
}
我还有一个函数,可以返回一些静态数据以满足测试要求:
private IQueryable<User> MockedGetAll()
{
List<User> users = new List<User>();
users.Add(new User(1, "mark.paterson", "mark.paterson@yahoo.com", "Mark", "Paterson", false, true));
users.Add(new User(2, "nikki.paterson", "nikki.paterson@yahoo.com", "Nikki", "Paterson", false, true));
return users.AsQueryable();
}
private IQueryable MockedGetAll()
{
列表用户=新列表();
添加新用户(1,“mark.paterson”,“mark。paterson@yahoo.com“,”马克“,”帕特森“,”假“,”真“);
添加新用户(2,“nikki.paterson”,“nikki。paterson@yahoo.com,“Nikki”,“Paterson”,假,真);
返回users.AsQueryable();
}
测试在“Assert.Greater”处中断。我得到的是0条记录,而不是2条记录。当我调试代码时,代码实际上返回了数据库调用的结果,应该是0条记录,而不是模拟的数据。下面的一行正在消除一切,并在控制器和数据访问层之间引入了一个不可能单独进行单元测试的强耦合:
IUserRepository repo = new UserRepository();
绝对不要在任何应用程序(不仅仅是ASP.NET MVC)中编写类似的内容。无论你做什么,如果你写这样的代码,它总是会在你的单元测试中断,你将无法测试它
这是不可能进行模拟/单元测试的
您应该使用构造函数注入来削弱层之间的耦合:
public class UserController : Controller
{
private readonly IUserRepository _repo;
public UserController(IUserRepository repo)
{
_repo = repo;
}
public ActionResult Index()
{
return RedirectToAction("List");
}
public ActionResult List()
{
IQueryable<Business.Entities.User> users = _repo.GetAll();
return View("List", users);
}
}
我提供这一点是为了说明另一件你绝对不应该做的事情,并强调这是一个事实
还讨论了中的这些问题
private readonly IUserRepository _repo;
public UserController(IUserRepository repo)
{
_repo = repo;
}
public UserController(): this(new UserRepository())
{
}