正如标题所示,我正在寻找如何正确测试控制器扩展的方向.该扩展呈现一个部分视图,反过来我在
JSONResult中使用:
public static string RenderPartialViewToString(this Controller controller,string viewName = null,object model = null) { if (string.IsNullOrEmpty(viewName)) { viewName = controller.ControllerContext.RouteData.GetrequiredString("action"); } controller.ViewData.Model = model; using (StringWriter sw = new StringWriter()) { ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext,viewName); ViewContext viewContext = new ViewContext(controller.ControllerContext,viewResult.View,controller.ViewData,controller.TempData,sw); viewResult.View.Render(viewContext,sw); return sw.GetStringBuilder().ToString(); } }
使用示例
public JsonResult Foo() { var model = _repository.getSomeData(); return Json(new { html = this.RenderPartialViewToString("Index",model) },JsonRequestBehavior.AllowGet); }
我使用NUnit& MvcContrib test helper,但是当设置一个使用这个扩展的控制器时,我正在运行一个NRE.我假设控制器上下文设置不正确?
最终测试是在ViewEngines.Engines.FindPartialView上进行的.以下是失败测试的一部分:
var routeData = new RouteData(); routeData.Values.Add("controller","someName"); routeData.Values.Add("action","someAction"); var builder = new TestControllerBuilder(); var controller = new ListingController(repository.Object); builder.RouteData = routeData; builder.InitializeController(controller); var result = controller.Foo();
解决方法
您将不得不向ViewEngines.Engines集合添加一个嘲笑视图引擎,以便您可以模拟FindPartialView调用.这是Rhino Mocks的一个例子:
var view = MockRepository.GenerateStub<IView>(); var engine = MockRepository.GenerateStub<IViewEngine>(); var viewEngineResult = new ViewEngineResult(view,engine); engine .Stub(x => x.FindPartialView(null,null,false)) .IgnoreArguments() .Return(viewEngineResult); ViewEngines.Engines.Add(engine);
那么你可以声明view.Render方法被调用,拦截它的参数并写一些嘲笑的数据到这个写入器,最后断言你的控制器操作返回这个嘲笑的字符串.