How to write Unit Test for JsonResult Return method with RenderPartialViewToString?

If you look at an example at this link:

http://www.atlanticbt.com/blog/asp-net-mvc-using-ajax-json-and-partialviews/

How to write unit test for JsonAdd method? I have a similar situation in my own code, but RenderPartialViewToString errors when called:

ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView

I tried different ways to try to drown out this call to no avail. Any help appreciated. Thanks.

+3
unit-testing model-view-controller mvccontrib rhino-mocks
source share
2 answers

Since ViewEninges is a static class, you cannot mock it with RhinoMocks. I find it best to create a "partial image viewer" interface. The interface is a mock one, so you can limit the complexity of rendering a view. Here are some quick pseudo codes thrown together.

First, define the partial view visualization interface:

public interface IRenderPartialView { string Render(string viewName, object model); } 

Then change the base class RenderPartialViewToString to the implementation of IRenderPartialView.Render:

 public abstract class BaseController : Controller, IRenderPartialView { ... public string Render(string viewName, object model) { // same code as RenderPartialViewToString } } 

Now we need to change the designers of the controller so that we can implement IRenderPartialView during testing, but use the base class in the production process. We can do this using a couple of constructors:

 public class YourController : BaseController { private IRenderPartialView partialRenderer; public YourController() { SetRenderer(this); } public YourController(IRenderPartialView partialRenderer) { SetRenderer(partialRenderer); } private void SetRenderer(IRenderPartialView partialRenderer) { this.partialRenderer = this; } } 

Now JsonAdd can invoke a partial view renderer:

 public JsonResult JsonAdd(AddPersonViewModel AddPersonModel) { ... return Json(new { Success = true, Message = "The person has been added!", PartialViewHtml = partialRenderer.Render("PersonList", new PersonListViewModel {PersonList = _personList}) }); } 

So, during testing, you will mock IRenderPartialView and send this to a constructor that accepts IRenderPartialView . During production, when ASP.NET MVC calls your default constructor, it will use the controller as a visualization tool (having an implementation of IRenderPartialView.Render inside the base class).

+2
source share

I had a lot of problems to make unit test work with RenderPartialViewToString. I managed to do 2 things. I had to make fun of the view mechanism and the controller context.

Here is the code:

 public ViewEngineResult SetupViewContent(string viewName, string viewHtmlContent) { var mockedViewEngine = new Mock<IViewEngine>(); var resultView = new Mock<IView>(); resultView.Setup(x => x.Render(It.IsAny<ViewContext>(), It.IsAny<TextWriter>())) .Callback<ViewContext, TextWriter>((v, t) => { t.Write(viewHtmlContent); }); var viewEngineResult = new ViewEngineResult(resultView.Object, mockedViewEngine.Object); mockedViewEngine.Setup(x => x.FindPartialView(It.IsAny<ControllerContext>(), viewName, It.IsAny<bool>())) .Returns<ControllerContext, string, bool>((controller, view, useCache) => { return viewEngineResult; }); mockedViewEngine.Setup(x => x.FindView(It.IsAny<ControllerContext>(), viewName, It.IsAny<string>(), It.IsAny<bool>())) .Returns<ControllerContext, string, string, bool>((controller, view, masterName, useCache) => { return viewEngineResult; }); ViewEngines.Engines.Clear(); ViewEngines.Engines.Add(mockedViewEngine.Object); return viewEngineResult; } public void SetContext(ref PointCollecteLivraisonController controller) { SetupViewContent("MyViewName", "TheViewContent"); var httpContextBase = new Mock<HttpContextBase>(); var httpRequestBase = new Mock<HttpRequestBase>(); var response = new Mock<HttpResponseBase>(); var session = new Mock<HttpSessionStateBase>(); var routes = new RouteCollection(); RouteConfigurator.RegisterRoutes(routes); var routeData = new RouteData(); routeData.Values.Add("controller", "PointCollecteLivraison"); routeData.Values.Add("action", "RechercheJson"); httpContextBase.Setup(x => x.Response).Returns(response.Object); httpContextBase.Setup(x => x.Request).Returns(httpRequestBase.Object); httpContextBase.Setup(x => x.Session).Returns(session.Object); session.Setup(x => x["somesessionkey"]).Returns("value"); httpRequestBase.Setup(x => x.Form).Returns(new NameValueCollection()); controller.ControllerContext = new ControllerContext(httpContextBase.Object, routeData, controller); controller.Url = new UrlHelper(new RequestContext(controller.HttpContext, routeData), routes); } 

And so I use all of this:

 PointCollecteLivraisonController controller = new PointCollecteLivraisonController(); SetContext(ref controller); 

Here are my sources: View engine movements: http://thoai-nguyen.blogspot.fr/2011/04/test-mock-mvc-view-engine.html

Mocking controller context: ASP.NET MVC - unit testing of RenderPartialViewToString () with Moq framework?

I hope for this help.

+6
source share

All Articles