【发布时间】:2014-05-27 10:16:08
【问题描述】:
下面是一个带有 Post 方法的控制器。如何在不将更改保存到数据库的情况下针对 CREATE 方法编写单元测试?
我正在尝试针对我的控制器编写测试,以便当其他开发人员更改代码时它不会破坏我的功能(我在 Create 方法上有一点功能,以保持它现在的简单性)。
public class AdministratorController : Controller
{
private IUnitOfWork _uow;
[HttpPost]
public ActionResult Create(MyModel model)
{
ViewBag.id = model.Id;
if (model.FirstName == model.LastName)
{
ModelState.AddModelError("", "Cannot have same first name and last name.");
}
if (ModelState.IsValid)
{
MyClass record = new MyClass();
record.SAFirstName = model.FirstName;
record.SALastName = model.LastName;
record.SATitle = model.Title;
record.SAEmail = model.EmailAddress;
record.Since = DateTime.Now;
_uow.AdministratorRepository.AddRecord(record);
_uow.SaveChanges();
return RedirectToAction("Index", "Administrator");
}
return View(model);
}
}
2.) 我的 UOW 看起来像这样:
公共类 UnitOfWork : IUnitOfWork { 私有只读 MasterContext _context;
public UnitOfWork(MasterContext context)
{
_context = context;
}
public UnitOfWork()
{
_context = new MasterContext();
}
public void SaveChanges()
{
_context.SaveChanges();
}
private IAdministratorRepository _Repo;
public IAdministratorRepository AdministratorRepository
{
get
{
if (this._Repo == null)
{
this._Repo = new IAdministratorRepository(_context);
}
return _Repo;
}
}
3) 我的 AdministratorRepository 构造函数如下所示:
private readonly MasterContext _context;
public AdministratorRepository(MasterContext context)
{
_context = context;
}
【问题讨论】:
-
经典答案是,你不知道。你抽象出像数据库这样的东西。但是,我的新想法是,您可以使用 SQL CE 或 SQL Server LocalDB 创建一个用于测试生命周期的数据库。
-
您已经完成了艰苦的工作,将您的数据库访问抽象到一个可模拟的接口后面。只需创建一个模拟您想要的操作的存根,或使用一个模拟框架。如果你有任何直接传递 Linq 的方法,你会遇到一些问题,因为 Linq to Entities 的行为与 Linq to Objects 略有不同,这是大多数模拟框架会使用的。
标签: c# asp.net-mvc unit-testing mocking