Asp.net mvc 在单元测试呈现局部视图的控制器扩展上寻找方向

Asp.net mvc 在单元测试呈现局部视图的控制器扩展上寻找方向,asp.net-mvc,asp.net-mvc-3,unit-testing,nunit,mvccontrib-testhelper,Asp.net Mvc,Asp.net Mvc 3,Unit Testing,Nunit,Mvccontrib Testhelper,正如标题所说,我正在寻找如何正确测试控制器扩展的方向。扩展呈现一个局部视图,我在JSONResult中使用该视图: public static string RenderPartialViewToString(this Controller controller, string viewName = null, object model = null) { if (string.IsNullOrEmpty(viewName)) {

正如标题所说,我正在寻找如何正确测试控制器扩展的方向。扩展呈现一个局部视图,我在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&the,然而,当设置一个使用此扩展的控制器时,我遇到了一个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 Mock的一个示例:

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);
var view=MockRepository.GenerateStub();
var engine=MockRepository.GenerateStub();
var viewEngineResult=新viewEngineResult(视图,引擎);
发动机
.Stub(x=>x.FindPartialView(null,null,false))
.IgnoreArguments()
.返回(查看引擎结果);
ViewEngines.Engines.Add(引擎);

然后,您可以断言调用了view.Render方法,截取其参数并向该编写器写入一些模拟数据,最后断言控制器操作返回了这个模拟字符串。

我只是拍了拍自己的额头,引用了V8广告。啊!谢谢你指出我看不见的明显的东西。可以肯定的是,我是认真的,不是开玩笑的。在MVC4中,在添加模拟引擎之前,您可能必须先执行ViewEngines.Engines.Clear()。至少在从MVC3升级到MVC4之后,我必须这样做才能让它正常工作。