使用DI在ASP.NET中从前到后对控制器进行单元测试的最佳策略

时间:2011-12-13 19:53:50

标签: asp.net unit-testing controller castle

我是DI的新手,对单元测试控制器的最佳策略有疑问。

我有一个控制器,它使用DI来获取存储库,mappingengine和logger。这基本上就是我从Kozmics示例应用程序中学到的。

private readonly IRepository repository;
private readonly IMappingEngine mappingEngine;
private readonly ILogger logger;

public DossierController(IRepository repository, IMappingEngine mappingEngine, ILogger logger)
{
  this.repository = repository;
  this.mappingEngine = mappingEngine;
  this.logger = logger;
}

现在我有一个方法被调用来保存档案。在方法内部,dossiermodel被映射到档案并保存到数据库中。

[HttpPost]
[ActionName("Dossier")]
[AcceptVerbs(HttpVerbs.Post)]
[AcceptParameter(Name = "button", Value = "save")]
public ActionResult Dossier_Save(string button, DossierModel dossierModel, string returnUrl)
{
  if (!Request.IsAuthenticated)
    return RedirectToAction("Index", "Home");

  if (!ModelState.IsValid) return View(dossierModel);

  Dossier dossier = mappingEngine.Map<DossierModel, Dossier>(dossierModel);
  dossier.DigitaleHandtekeningDatum = new DateTime(2011, 11, 11);

  repository.TransactionBegin();
  repository.Save(dossier);
  repository.TransactionCommit();

  return View();
}

我想测试控制器以确保两件事:1档案正确映射; 2档案实际上完全保留在数据库中。

现在我的问题是:对此最好的策略是什么?我应该:

  • 整体测试控制器?如果是这样的话?
  • 嘲笑持久性?然后我如何测试对象是否实际持久化?

这应该在一个单独的unittest中完成,专门用于测试数据库持久性吗?

2 个答案:

答案 0 :(得分:0)

首先,我认为你可能想要使用[Authorize]属性而不是测试Request.IsAuthenticated。它将消除模拟整个Request对象的复杂性。

然后我会模拟存储库,并测试使用正确的参数调用Save方法(或者不调用,具体取决于您正在测试的用例)

答案 1 :(得分:0)

我不会对此进行单元测试。在此博客上查看单元测试的成本和收益的可视化:http://blog.stevensanderson.com/2009/11/04/selective-unit-testing-costs-and-benefits/。我认为控制器通常具有高级别的依赖性和低复杂度,就像图中的协调器一样。将您的单元测试保存到实际受益的代码,例如算法,状态机等。您可以使用浏览器自动化集成测试控制器逻辑,或者如果您想进入,可以使用类似http://blog.stevensanderson.com/2009/06/11/integration-testing-your-aspnet-mvc-application/的内容控制器级别。