我有一个实体实现了简单的添加操作和重定向到详细页面控制器:单位在ASP.NET MVC 2测试控制器RedirectToAction
[HttpPost]
public ActionResult Add(Thing thing)
{
// ... do validation, db stuff ...
return this.RedirectToAction<c => c.Details(thing.Id));
}
这个伟大的工程(使用从RedirectToAction MvcContrib程序集)。
当我单元测试此方法时,我想访问从Details操作返回的ViewData(这样我就可以获取新插入的主键并证明它现在在数据库中)。
测试有:
var result = controller.Add(thing);
但是导致这里是类型:System.Web.Mvc.RedirectToRouteResult
(这是一个System.Web.Mvc.ActionResult
)。它尚未执行Details方法。
我已经试过在返回的对象上调用ExecuteResult
传递模拟ControllerContext
,但是框架并不满意模拟对象中缺少细节。
我可以尝试填写详细信息等等,但然后我的测试代码比我测试的代码长,我觉得我需要为单元测试进行单元测试!
我在测试理念中错过了什么吗?当我无法恢复到返回状态时,如何测试此操作?
谢谢 - 这绝对有助于避免测试过程中框架的困难。所以,遵循这个习惯用法,我会对DBService进行单元测试,证明我可以添加东西,并为控制器进行单元测试,以证明其调用服务上的Save。但是我没有真正证明传入控制器的东西最终在数据库中。也许我可以用一堆更复杂的嘲讽规则来做到这一点......但是这并不正确,这是一个简单操作的很多测试锅炉板。 – 2010-03-13 23:16:42
那么,确定测试的范围和努力以及测试什么等等,都是我与之奋斗的事情。我认为你应该尝试将你的测试分为两类:单元测试和集成测试。单元测试应该只测试非常小的功能单元,比如上面的测试。集成测试应该考虑如何整合所有内容,也许涵盖您拥有的小用户故事。我宁愿将集成测试尽可能接近“真实”使用,例如运行WatiN并实际单击一些链接。根本不需要嘲笑。 – rmac 2010-03-13 23:43:06
如果你测试你的DBService,那你证明它是有效的。然后,你应该假设它可以并且它会正确处理数据库调用。所以如果你的控制器使用这个服务,你知道它会起作用。使用模拟框架,您可以验证传递给服务方法的参数,这就足够了。我认为rmacfie是对的,你可能试图做更深入的测试。 你的单元测试应该只包含一个动作,而不是一个完整的过程。 – 2010-03-14 23:53:29