寻找对呈现部分视图的控制器扩展进行单元测试的方向

发布于 2024-12-26 12:38:24 字数 1767 浏览 2 评论 0原文

正如标题所示,我正在寻找有关如何正确测试控制器扩展的指导。该扩展呈现一个部分视图,我又在 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 测试助手,但是在设置使用此扩展的控制器时,我'我遇到了 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();

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

独闯女儿国 2025-01-02 12:38:24

您必须将模拟的视图引擎添加到 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 方法被调用,拦截其参数并向此编写器写入一些模拟数据,最后断言您的控制器操作返回此模拟字符串。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文