Sta*_*anK 5 asp.net-mvc unit-testing asp.net-mvc-3
我在ActionResult上编写了一个扩展方法,用于单元测试,它将断言ViewName返回的是否是预期的.这是我到目前为止的代码:
public static void AssertViewWasReturned(this ActionResult result, string viewName)
{
    string actualViewName;
    if (result is ViewResult)
        actualViewName = (result as ViewResult).ViewName;
    else if (result is PartialViewResult)
        actualViewName = (result as PartialViewResult).ViewName;
    else
        throw new InvalidOperationException("Results of type " + result.GetType() + " don't have a ViewName");
    Assert.AreEqual(viewName, actualViewName, string.Format("Expected a View named{0}, got a View named {1}", viewName, actualViewName));
}
这工作正常,除非控制器返回视图而不指定名称 - 在这种情况下result.ViewName是一个空字符串.
所以,我的问题是 - 从ViewResult对象告诉ViewName是一个空字符串是什么?
如果你的控制器方法没有通过MVC管道调用,则附加信息不会添加到Controller.ViewData字典中(我假设它会以某种方式提供"操作"-key,但无法确认).但是,由于您在路由框架等的上下文"外部"使用控制器,因此无法知道被调用的方法.
所以答案就是"不".如果未指定视图的名称,则无法从操作返回的ViewResult中确定它.至少不是你的控制器的测试方式(顺便说一句,这完全没问题).
对于它的价值 - 我已经修改了我的测试我的扩展方法,如下所示(结合 J. Tihon 的反馈):
public static void AssertViewWasReturned(this ActionResult result, string viewName, string defaultViewName)
{    
    Assert.IsInstanceOf<ViewResultBase>(result, "Result is not an instance of ViewResultBase");
    var viewResult = (ViewResultBase)result;
    var actualViewName = viewResult.ViewName;
    if (actualViewName == "")
        actualViewName = defaultViewName;
    Assert.AreEqual(viewName, actualViewName, string.Format("Expected a View named{0}, got a View named {1}", viewName, actualViewName));
}
这意味着我的单元测试可以包含如下代码:
var result = controller.MyAction();
result.AssertViewWasReturned("ExpectedViewName","MyAction")
它没有我希望的那么好,因为我需要指定“defaultViewName”(即操作名称),但这是一个合理的妥协。
| 归档时间: | 
 | 
| 查看次数: | 12344 次 | 
| 最近记录: |