c# – 使用MVCContrib对单元测试MVC 3控制器和视图时,将Route和Values添加到RouteData

前端之家收集整理的这篇文章主要介绍了c# – 使用MVCContrib对单元测试MVC 3控制器和视图时,将Route和Values添加到RouteData前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
好的,所以我正在使用MVCContrib TestHelper来对我的控制器进行单元测试,这很有用.

像这么多人一样,通过单元测试我真的意味着这里的集成测试,我想至少确保我的视图在给出模型提供的情况下无错误地呈现…否则我可以错过一个基本上与模型相关的一类bug,甚至虽然我正在测试控制器(如果模型属性为null,则视图不呈现).

无论如何,我开始试图找出如何做到这一点(又名谷歌如何做到这一点).看起来最简单的方法是构造一个HTMLHelper,并且只是渲染视图(在这种情况下是局部的).

不幸的是,当我尝试使用我嘲笑的HTMLHelper时,它抱怨说没有路由数据中的控制器名称可用.

果然,我看到控制器RouteData没有填充.不幸的是RouteData.Values RouteValueDictionary是只读的,所以我不能提供必要的值.

我没有结婚HTMLHelper的想法来解决实际渲染视图作为测试的一部分的问题,所以随时建议替代品,但请不要打扰建议我使用Selenium,W​​atin或其他UI测试我的意见测试工具…我希望控件能够做一些操作和恢复状态和数据信息的一些测试,我不能用基于UI的测试.

这是我目前正在尝试渲染部分的代码

public class FakeView : IView
{
    #region IView Members
    public void Render(ViewContext viewContext,System.IO.TextWriter writer)
    {
        throw new NotImplementedException();
    }
    #endregion
}

public class WebTestUtilities
{
    public static void prepareCache()
    {
        SeedDataManager seed = new SeedDataManager();
        seed.CheckSeedDataStatus();
    }

    public static string RenderRazorViewToString(string viewName,object model,Controller controller)
    {
        var sb = new StringBuilder();
        var memWriter = new StringWriter(sb);
        var html = new HtmlHelper(new ViewContext(controller.ControllerContext,new FakeView(),new ViewDataDictionary(),new TempDataDictionary(),memWriter),new ViewPage());
        //This fails because it can't extract route information like the controller name)
        html.RenderPartial(viewName,model);
        return sb.ToString();
    }


    public void setupTestEnvironment(Controller controller)
    {
        RouteTable.Routes.Clear();
        RouteTable.Routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        RouteTable.Routes.MapRoute(
            "Default","{controller}/{action}/{id}",new { controller = "Main",action = "DefaultView",id = UrlParameter.Optional } 
        );




        ModelBinders.Binders[typeof(DateTime)] = new DateTimeModelBinder();
        ModelBinders.Binders[typeof(DateTime?)] = new DateTimeModelBinder();
        ModelMetadataProviders.Current = new DateTimeMetadataProvider();



    }
}

这里是我的测试方法

[TestMethod]
    public void GetUserTableView()
    {
        ViewResult result = controller.UserTable() as ViewResult;

        //I can populate the route and handler on the controller...
        RouteData routes = RouteTable.Routes.GetRouteData(controller.HttpContext);
        controller.RouteData.Route = routes.Route;
        controller.RouteData.RouteHandler = routes.RouteHandler;
        RouteValueDictionary routeKeys = new RouteValueDictionary();
        routeKeys.Add("controller","UserManagement");
        routeKeys.Add("action","UserTable");
        //But the RouteData.Values collection is read only :(
        controller.RouteData = new RouteData(){Values = routeKeys};
        string renderedView = WebTestUtilities.RenderRazorViewToString(result.ViewName,result.Model,controller);
    }

BTW,我得到的具体错误是:
RouteData必须包含一个名为“controller”的项,其值为非空字符串值.

解决方法

你可能已经完成了这个工作,但是我也遇到了类似的问题,并通过在控制器上重新设置ControllerContext来解决设置RouteData的情况,如下所示:
RouteData routeData = new RouteData();
routeData.Values.Add("someRouteDataProperty","someValue");
ControllerContext controllerContext = new ControllerContext { RouteData = routeData };
controller.ControllerContext = controllerContext;

然后在控制器RouteData.Values.ContainsKey(“someRouteDataProperty”)中工作,就像您在测试中设置的那样.

这是因为有一个无参数的ControllerContext的构造函数,故意在那里允许嘲笑等

猜你在找的C#相关文章