好的,我正在使用 MVCContrib TestHelper 对我的 Controller 进行单元测试,效果很好。
虽然像很多人一样,我在这里所说的单元测试实际上是指集成测试,我想至少确保我的 View 在给定提供的模型的情况下无错误地呈现......否则我可能会错过一整类基本上与以下相关的错误即使我正在测试 Controller (比如如果模型属性为 null 时 View 不呈现),模型也是如此。
无论如何,我开始尝试找出如何做到这一点(也就是谷歌搜索如何做到这一点)。看起来最简单的方法是构造一个 HTMLHelper 并让它只呈现 View (在本例中是部分 View )。
不幸的是,当我尝试使用模拟的 HTMLHelper 时,它会提示路由数据中没有可用的 Controller 名称。
果然,我看了一下, Controller RouteData 没有填充。不幸的是,RouteData.Values RouteValueDictionary 是只读的,所以我不能只提供必要的值。
我不赞同 HTMLHelper 的想法来解决实际渲染 View 作为测试的一部分的问题,所以请随意在那里提出替代方案,但请不要费心建议我使用 Selenium 测试我的 View ,Watin或其他 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);
}
顺便说一句,我得到的具体错误是: RouteData 必须包含名为“controller”且具有非空字符串值的项。
最佳答案
您可能已经解决了这个问题,但我只是遇到了类似的问题并通过重置 Controller 上的 ControllerContext 解决了设置 RouteData 的问题,如下所示:
RouteData routeData = new RouteData();
routeData.Values.Add("someRouteDataProperty", "someValue");
ControllerContext controllerContext = new ControllerContext { RouteData = routeData };
controller.ControllerContext = controllerContext;
然后在 Controller 中 RouteData.Values.ContainsKey("someRouteDataProperty") 按照您在测试中设置的方式工作。
这是有效的,因为有一个 ControllerContext 的无参数构造函数,它是故意允许模拟等的。
关于c# - 使用 MVCContrib 对 MVC 3 Controller 和 View 进行单元测试时,将键和值添加到 RouteData,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9831463/
当我使用Bundler时,是否需要在我的Gemfile中将其列为依赖项?毕竟,我的代码中有些地方需要它。例如,当我进行Bundler设置时:require"bundler/setup" 最佳答案 没有。您可以尝试,但首先您必须用鞋带将自己抬离地面。 关于ruby-我需要将Bundler本身添加到Gemfile中吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/4758609/
我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>
我有一个ModularSinatra应用程序,我正在尝试将Bootstrap添加到应用程序中。get'/bootstrap/application.css'doless:"bootstrap/bootstrap"end我在views/bootstrap中有所有less文件,包括bootstrap.less。我收到这个错误:Less::ParseErrorat/bootstrap/application.css'reset.less'wasn'tfound.Bootstrap.less的第一行是://CSSReset@import"reset.less";我尝试了所有不同的路径格式,但它
刚入门rails,开始慢慢理解。有人可以解释或给我一些关于在application_controller中编码的好处或时间和原因的想法吗?有哪些用例。您如何为Rails应用程序使用应用程序Controller?我不想在那里放太多代码,因为据我了解,每个请求都会调用此Controller。这是真的? 最佳答案 ApplicationController实际上是您应用程序中的每个其他Controller都将从中继承的类(尽管这不是强制性的)。我同意不要用太多代码弄乱它并保持干净整洁的态度,尽管在某些情况下ApplicationContr
我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以
我知道您通常应该在Rails中使用新建/创建和编辑/更新之间的链接,但我有一个情况需要其他东西。无论如何我可以实现同样的连接吗?我有一个模型表单,我希望它发布数据(类似于新View如何发布到创建操作)。这是我的表格prohibitedthisjobfrombeingsaved: 最佳答案 使用:url选项。=form_for@job,:url=>company_path,:html=>{:method=>:post/:put} 关于ruby-on-rails-rails:Howtomak
我有一个rubyonrails应用程序。我按照facebook的说明添加了一个像素。但是,要跟踪转化,Facebook要求您将页面置于达到预期结果时出现的转化中。即,如果我想显示客户已注册,我会将您注册后转到的页面作为成功对象进行跟踪。我的问题是,当客户注册时,在我的应用程序中没有登陆页面。该应用程序将用户带回主页。它在主页上显示了一条消息,所以我想看看是否有一种方法可以跟踪来自Controller操作而不是实际页面的转化。我需要计数的Action没有页面,它们是ControllerAction。是否有任何人都知道的关于如何执行此操作的gem、文档或最佳实践?这是进入布局文件的像素
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha
当谈到运行时自省(introspection)和动态代码生成时,我认为ruby没有任何竞争对手,可能除了一些lisp方言。前几天,我正在做一些代码练习来探索ruby的动态功能,我开始想知道如何向现有对象添加方法。以下是我能想到的3种方法:obj=Object.new#addamethoddirectlydefobj.new_method...end#addamethodindirectlywiththesingletonclassclass这只是冰山一角,因为我还没有探索instance_eval、module_eval和define_method的各种组合。是否有在线/离线资