单元测试我的控制器方法导致一个空的ViewName? [英] Unit testing my controller method results in an empty ViewName?

查看:103
本文介绍了单元测试我的控制器方法导致一个空的ViewName?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



当我检查 ViewName proprty,从返回的 ViewResult 对象,它的(空)。



我的印象是 ViewName 是由 View (关于ASP的此MS文章建议)。 NET MVC控制器测试)。



BTW,当我测试ViewData时,它是一切正确的。



这是代码我有...

  public ActionResult Index(int?page,string tag)
{
if(page == null || page< = 0)
{
page = 1;
}

var viewData = new IndexViewData
{
... my property setters,etc ...
};
return View(viewData);
}

[TestMethod]
public void Index_Action_Should_Return_Index_View_For_Default_HomePage()
{
// Arrange。
var controller = PostController; //包装,因为我使用D.I.

// Act。
ViewResult viewResult = controller.Index(null,null)as ViewResult;

//断言。
Assert.IsNotNull(viewResult);
Assert.AreEqual(Index,viewResult.ViewName); //这是false / failed。

var indexViewData = viewResult.ViewData.Model as IndexViewData;
Assert.IsNotNull(indexViewData); // 这是真的。
}


解决方案

ViewName你在ViewResult中设置它。如果您的View名称与您的控制器名称匹配,那么我将检查以确保ViewName为空或为空,因为这将是(IMO)正确的行为,因为您不想在视图上设置名称。我只检查ViewName是否设置,当我打算返回的视图不匹配的操作 - 例如,当返回错误视图,例如。



EDIT :以下是ViewResultBase.cs中的ExecuteResult的源代码(来自RC1,我在Macintosh上没有RTW的源代码)。正如你可以看到,它检查ViewName是否已被直接设置,如果没有,它从控制器上下文的路由数据中的操作拉它。

  public override void ExecuteResult(ControllerContext context){
if(context == null){
throw new ArgumentNullException(context);
}
if(String.IsNullOrEmpty(ViewName)){
ViewName = context.RouteData.GetRequiredString(action);
}

ViewEngineResult result = null;

if(View == null){
result = FindView(context);
View = result.View;
}

ViewContext viewContext = new ViewContext(context,View,ViewData,TempData);
View.Render(viewContext,context.HttpContext.Response.Output);

if(result!= null){
result.ViewEngine.ReleaseView(context,View);
}
}


I'm doing some simple MS unit tests on my standard, nothing special controller.

When I check the ViewName proprty, from the returned ViewResult object, it's "" (empty).

I'm under the impression that the ViewName is implied by the name of the View (as suggested by this MS article on ASP.NET MVC controller testing).

BTW, when I test the ViewData, it's all there and correct.

Here's the code I have...

public ActionResult Index(int? page, string tag)
{
    if (page == null || page <= 0)
    {
        page = 1;
    }

    var viewData = new IndexViewData
                       {
                       ... my property setters, etc ...
                       };
    return View(viewData);
}

[TestMethod]
public void Index_Action_Should_Return_Index_View_For_Default_HomePage()
{
    // Arrange.
    var controller = PostController; // Wrapper, cause I use D.I.

    // Act.
    ViewResult viewResult = controller.Index(null, null) as ViewResult;

    // Assert.
    Assert.IsNotNull(viewResult);
    Assert.AreEqual("Index", viewResult.ViewName); // This is false/fails.

    var indexViewData = viewResult.ViewData.Model as IndexViewData;
    Assert.IsNotNull(indexViewData); // This is true.
}

解决方案

The ViewName is only present when you set it in the ViewResult. If your View name matches your controller name, then I would check to ensure that the ViewName is null or empty as that would be (IMO) the correct behavior since you wouldn't want to set a name on the view. I only check that the ViewName is set when I intend that the View to be returned does not match the action -- say, when returning the "Error" view, for example.

EDIT: The following is the source for ExecuteResult in ViewResultBase.cs (from RC1, I don't have the source for RTW on my Macintosh). As you can see it checks to see if the ViewName has been set directly and if not, it pulls it from the action in the controller context's route data. This only happens in ExecuteResult, which is invoked AFTER your controller's action has completed.

    public override void ExecuteResult(ControllerContext context) {
        if (context == null) {
            throw new ArgumentNullException("context");
        }
        if (String.IsNullOrEmpty(ViewName)) {
            ViewName = context.RouteData.GetRequiredString("action");
        }

        ViewEngineResult result = null;

        if (View == null) {
            result = FindView(context);
            View = result.View;
        }

        ViewContext viewContext = new ViewContext(context, View, ViewData, TempData);
        View.Render(viewContext, context.HttpContext.Response.Output);

        if (result != null) {
            result.ViewEngine.ReleaseView(context, View);
        }
    }

这篇关于单元测试我的控制器方法导致一个空的ViewName?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆