5

In a testing situation, I'd like to be able to use the default viewEngine to render a given ViewResult to HTML.

Currently, my views are WebForms-based. But I might have Spark or Razor views at some point. For now, I'd like to focus on WebForms. Can I render my views from a test?

2
  • You may want to consider browser based testing. That way you could support testing AJAX or javascript interaction. Commented Aug 19, 2011 at 23:54
  • 1
    I have browser-based testing also through Selenium. But I am trying to test the actual HTML/Javascript that is being rendered. Commented Aug 20, 2011 at 0:45

1 Answer 1

7

Here's a method that will let you render a ViewResult to a string. The only tricky part to using it in your context will be to Mock up a viable ControllerContext.

static string RenderPartialViewToString(ControllerContext context, ViewResultBase partialViewResult)
    {
        Require.ThatArgument(partialViewResult != null);
        Require.That(context != null);
        using (var sw = new StringWriter())
        {
            if (string.IsNullOrEmpty(partialViewResult.ViewName))
            {
                partialViewResult.ViewName = context.RouteData.GetRequiredString("action");
            }
            ViewEngineResult result = null;
            if (partialViewResult.View == null)
            {
                result = partialViewResult.ViewEngineCollection.FindPartialView(context, partialViewResult.ViewName);
                if(result.View == null)
                    throw new InvalidOperationException(
                                   "Unable to find view. Searched in: " +
                                   string.Join(",", result.SearchedLocations));
                partialViewResult.View = result.View;
            }

            var view = partialViewResult.View;
            var viewContext = new ViewContext(context, view, partialViewResult.ViewData,
                                              partialViewResult.TempData, sw);
            view.Render(viewContext, sw);
            if (result != null)
            {
                result.ViewEngine.ReleaseView(context, view);
            }
            return sw.ToString();
        }
    }
Sign up to request clarification or add additional context in comments.

2 Comments

Very helpful, thanks. Is there any blog post or other kind of explanation regarding how this was produced?
@Jon: I just used ILSpy to see what ViewResultBase.ExecuteResult does, and modified it to use a StringWriter instead of the request output stream. (I had to delve into PartialViewResult.FindView for part of it, too, since that's a protected method. The Require.That statements are just a concise way to say if(!...) throw....

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.