获取View View Name,其中ViewResult.ViewName为单元测试的空字符串

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));
}
Run Code Online (Sandbox Code Playgroud)

这工作正常,除非控制器返回视图而不指定名称 - 在这种情况下result.ViewName是一个空字符串.

所以,我的问题是 - 从ViewResult对象告诉ViewName是一个空字符串是什么?

J. *_*hon 6

如果你的控制器方法没有通过MVC管道调用,则附加信息不会添加到Controller.ViewData字典中(我假设它会以某种方式提供"操作"-key,但无法确认).但是,由于您在路由框架等的上下文"外部"使用控制器,因此无法知道被调用的方法.

所以答案就是"不".如果未指定视图的名称,则无法从操作返回的ViewResult中确定它.至少不是你的控制器的测试方式(顺便说一句,这完全没问题).


Sta*_*anK 5

对于它的价值 - 我已经修改了我的测试我的扩展方法,如下所示(结合 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));
}
Run Code Online (Sandbox Code Playgroud)

这意味着我的单元测试可以包含如下代码:

var result = controller.MyAction();
result.AssertViewWasReturned("ExpectedViewName","MyAction")
Run Code Online (Sandbox Code Playgroud)

它没有我希望的那么好,因为我需要指定“defaultViewName”(即操作名称),但这是一个合理的妥协。