我是 DI 新手,对控制器单元测试的最佳策略有疑问。
我有一个控制器,它使用 DI 来获取存储库、映射引擎和记录器。这基本上就是我从 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;
}
现在我有一个被调用的方法来保存达析报告。在该方法内部,达析报告模型被映射到达析报告并保存到数据库中。
[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 达析报告实际上完全保留在数据库中。
现在我的问题是:最好的策略是什么?我应该:
- 对整个控制器进行单元测试吗?如果是的话怎么办?
- 嘲笑坚持?那么如何测试对象是否真正被持久化呢?
这应该在专门用于测试数据库持久性的单独单元测试中完成吗?
I'm new to DI and have a question about the best strategy for unit testing a controller.
I have a controller that uses DI to get the repository, mappingengine and logger. This is basically how i learned it from Kozmics sample application.
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;
}
Now I have a method that is called to save a dossier. Inside the method the dossiermodel is mapped to a dossier and saved to the database.
[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();
}
I want to test the controller to make sure of two things: 1 that the dossier is correctly mapped and 2 that the dossier is actually completely persisted in the database.
Now my question is: what is the best strategy for this? Should I:
- Unit test the controller as a whole? And if so how?
- Mock the persistence? Then how do I test if the object is actually persisted?
Should this be done in a separate unittest specifically for testing the database persistence?
发布评论
评论(2)
首先,我认为您可能想使用 [Authorize] 属性而不是测试 Request.IsAuthenticated。它将消除模拟整个 Request 对象的复杂性。
然后,我将模拟存储库,并测试是否使用正确的参数调用 Save 方法(或不调用,具体取决于您正在测试的用例)
First I think you probably want to use the [Authorize] attribute instead of testing Request.IsAuthenticated. It will remove the complexity of mocking the whole Request object.
I would then mock the repository, and test that the Save method is called with the right parameters (or not called, depending on the use case you are testing)
我不会对此进行单元测试。在此博客中查看单元测试成本和收益的可视化: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/ 如果您想进入控制器级别。
I would not unit test this. Take a look at the visualization of costs and benefits of unit testing at this blog: http://blog.stevensanderson.com/2009/11/04/selective-unit-testing-costs-and-benefits/. I would argue that controllers typically have a high level of dependencies and a low level of complexity, just like a coordinator in the graph. Save your unit testing to the code that actually benefits from it, like algorithms, state machines, etc. You can integration test your controller logic using browser automation or you can use something like this http://blog.stevensanderson.com/2009/06/11/integration-testing-your-aspnet-mvc-application/ if you want to go in at the controller level.