关于单元测试如何与我当前项目的设计相结合,我有点迷失。我目前的测试都是集成测试,最终只测试第三方ORM。我以为我需要使用Repository模式,但我不清楚如何在应用程序中添加它作为一个层。这是我正在使用的一个基本对象示例:
public class Venue : ModelBase<Venue>
{
public Venue ()
: base()
{
}
public virtual string VenueName { get; set; }
}
及其行动:
[HttpGet]
public ActionResult Create ()
{
return View();
}
public ActionResult Create ([ModelBinder(typeof(VenueBinder))]Venue Venue)
{
Venue.Save();
return RedirectToAction("List", "Venue");
}
[HttpGet]
public ActionResult Edit (long id)
{
return View(Venue.Load(id));
}
[HttpPost]
public ActionResult Edit ([ModelBinder(typeof(VenueBinder))]Venue v, long id)
{
VenueBinder.EditModel(v, id);
return RedirectToAction("List", "Venue");
}
public ActionResult Delete (long id)
{
Venue temp = Venue.Load(id);
var eventController = new EventController();
foreach (var e in Event.All().ToList().FindAll(x => x.Venue.ID == id))
{
eventController.Delete(e.ID);
}
temp.Delete();
return RedirectToAction("List", "Venue");
}
和模型活页夹:
public class VenueBinder : IModelBinder
{
/// <summary>
/// bind form data to Venue model
/// </summary>
public object BindModel (ControllerContext controllerContext, ModelBindingContext bindingContext)
{
return new Venue
{
VenueName = bindingContext.ValueProvider.GetValue("name").AttemptedValue
};
}
/// <summary>
/// edits an existing Venue object
/// </summary>
public static void EditModel (Venue v, long id)
{
Venue temp = Venue.Load(id);
temp.VenueName = v.VenueName;
temp.Save();
}
}
答案 0 :(得分:1)
如果要单独测试控制器操作,则必须抽象可以在模型上执行的CRUD操作,控制器将作为构造函数依赖关系接口。在单元测试中,您可以向控制器提供此接口的模拟实例,并能够对其进行定义。
话虽如此,过多的抽象并不总是一件好事,你不应仅仅为了单元测试而这样做。如果他们没有为您的站点带来其他价值,例如在其他应用程序中有可重用的存储库层,您可能不应该这样做。集成测试也很好。您只需确保对每个测试处于可预测状态的数据执行此操作,最好在每次测试之前填充并在其后拆除。希望您的ORM支持此功能。 Jimmy Bogard写了一篇关于限制你的抽象主题的nice blog post。