我想要一个很好的方式来清理我的控制器,使他们更可测试,而不必依赖于一个常量的数据库连接。我认为我有一个体面的开始,用IObjectContext抽象出我的对象上下文。这适用于上下文,但我的下一个问题是我有一个generic repository,我在整个项目中使用了许多操作方法(请参阅下面的代码)。干净的方式来测试ASP.NET MVC控制器不击中数据库?
除了默认构造函数外,我的控制器还包含一个接受IObjectContext(简单依赖注入)的重载。在我的单元测试中,我可以轻松地模拟IObjectContext。我的问题是在各种操作方法中处理我的通用存储库。我可以向控制器添加一些额外的构造函数重载,但是恐怕这会很麻烦,很快。然而,由于没有这样做,我根本无法想到一种干净的方法来提高可测试性,因此我不必依靠数据库连接。
有没有简单的解决方案,我忽略了?
/// <summary>
/// Initializes a new instance of the HomeController class
/// </summary>
public HomeController(IObjectContext context)
{
_context = context;
}
/// <summary>
/// GET: /home/index
/// </summary>
/// <returns>Renders the home page</returns>
public ActionResult Index()
{
List contacts;
HomeViewModel model;
using (IRepository<Contact> repository = new DataRepository<Contact>(_context))
{
contacts = new List(repository.GetAll());
}
model = new HomeViewModel(contacts);
return View(model);
}
如果我必须去增加额外的构造函数重载,以适应我的顾虑的途径,我正在考虑加入一些私人性质的(直到需要时它会deffer存储库的实例化),以我的控制器,用于动作方法使用的每个存储库。例如:
private IRepository<Contact> _contactRepository;
private IRepository<Contact> ContactRepository
{
get
{
return _contactRepository ?? (_contactRepository = new DataRepository<Contact>());
}
}
对于单元测试目的,我可以使用构造函数重载预先初始化存储库。
你对此有何看法?我是否错过了一些应该明显的清洁剂?
你可以嘲笑你的存储库吗? – Pace 2010-02-17 13:25:50
谢谢你的回应。这实际上是我的观点。我当然可以,但是有没有一种干净的方式来实现我的控制器,这样我就不会为每个使用另一个存储库的可能操作方法重载构造函数。例如,一种行为方法依赖于几个不同的存储库。 – senfo 2010-02-17 13:33:47