Looking for direction on unit testing a controller extension that renders a partial view

霸气de小男生 提交于 2019-11-30 13:56:29

问题


As the title says, I'm looking for direction on how to properly test a controller extension. The extension renders a partial view which in turn I'm using within a 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();
            }
        }

Example usage:

public JsonResult Foo()
{
    var model = _repository.getSomeData();

    return Json(new { html = this.RenderPartialViewToString("Index", model) }, JsonRequestBehavior.AllowGet);
}

I'm using NUnit & the MvcContrib test helper, however when setting up a controller that makes use of this extension I'm running into a NRE. I'm assuming that the controller context is not setup correctly?

Ultimately the test is barfing on ViewEngines.Engines.FindPartialView. Here is a portion of the failing test:

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();

回答1:


You will have to add a mocked view engine to the ViewEngines.Engines collection so that you can mock the FindPartialView call. Here's an example with 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);

Then you could assert that the view.Render method was called, intercept its arguments and write some mocked data to this writer and finally assert that your controller action returned this mocked string.



来源:https://stackoverflow.com/questions/8859077/looking-for-direction-on-unit-testing-a-controller-extension-that-renders-a-part

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!