title: How to test controller action that serializes a view
body: <p>Alright so I am trying to test a controller result to make sure it is returning the right values but I am running into a number of problems with mocking controller contexts. All I want to do is test if someone enters a number on a page if the JsonResult is success = true.  However in the controller I serialize a partial view and return some HTML that contains all the data that is pertinent to the request number.  I am comfortable with setting up the expected results in the json result, but I can't even get the test to advance to that far.  The test gets hung up when serializing the partial view.  I don't really care to test that but I don't know how to work around the result of that function other than the create some fakes for the controllercontext and let it search for an serialize the view.</p>
  
  <p>Here is the controller</p>
  
  <pre><code>[HttpPost]
  [RecaptchaControlMvc.CaptchaValidator]
  public JsonResult GetPublicInformation(PublicPortalViewModel model, bool captchaValid)
  {
      if (captchaValid == true)
      {
          //check to see if their is a request number to look up the request by
          if (model.RequestNumber != null)
          {
              //fill model data using by calling the service
              model = _service.GetPublicPortalData(model);
              var content = base.SerializeView("DisplayPublicInformation", model);
              return Json(new { success = true, htmlContent = content });
          }
          else
          {
              return Json(new { success = false, htmlContent = "&lt;span style=\"color: red;\"&gt;No request was found with that number, please enter a valid request number.&lt;/span&gt;" });
          }
      }
      else
      {
          return Json(new { success = false, htmlContent = "&lt;span style=\"color: red;\"&gt;Please enter a valid Captcha Value&lt;/span&gt;" });
      }
  }
  </code></pre>
  
  <p>Specifically I am having problems with this line:</p>
  
  <pre><code>var content = base.SerializeView("DisplayPublicInformation", model);
  </code></pre>
  
  <p>Here is the definition of that function:</p>
  
  <pre><code>protected internal virtual string SerializeView(string viewName, object model)
  {
      if (string.IsNullOrEmpty(viewName))
          viewName = ControllerContext.RouteData.GetRequiredString("action");
  
      this.ViewData.Model = model;
  
      using (var sw = new StringWriter())
      {
          // keep getting null reference errors on this line when I write my tests .
          var viewResult = ViewEngines.Engines.FindPartialView(this.ControllerContext, viewName);
          var viewContext = new ViewContext(this.ControllerContext, viewResult.View, this.ViewData, this.TempData, sw);
          // render the view into the stringwriter class
          viewResult.View.Render(viewContext, sw);
          // output the rendered string
          return sw.GetStringBuilder().ToString();
      }
  }
  </code></pre>
  
  <p>Here is my test which I apologize for being so messy but I wanted to post where I am at currently.  I know there is more code than needed.</p>
  
  <pre><code>private PartialViewResult _result;
  private Mock&lt;HttpContextBase&gt; _mockHttpContext;
  private HttpContextBase _httpContext;
  private RouteData _routeData;
  private RouteData _parentRouteData;
  
  protected Mock&lt;HttpContextBase&gt; HttpContextBaseMock;
  protected Mock&lt;HttpRequestBase&gt; HttpRequestMock;
  protected Mock&lt;HttpResponseBase&gt; HttpResponseMock;
  
  [Test]
  public void GetPublicInformationValidRequestNumber()
  {
      var sut = new PublicPortalController();
      SetupRouteData();
      HttpContextBaseMock = new Mock&lt;HttpContextBase&gt;();
      HttpContextBaseMock.SetupAllProperties();
      HttpRequestMock = new Mock&lt;HttpRequestBase&gt;();
      HttpResponseMock = new Mock&lt;HttpResponseBase&gt;();
      HttpContextBaseMock.SetupGet(x =&gt; x.Request).Returns(HttpRequestMock.Object);
      HttpContextBaseMock.SetupGet(x =&gt; x.Response).Returns(HttpResponseMock.Object);
  
      var browser = new Mock&lt;HttpBrowserCapabilitiesBase&gt;(MockBehavior.Strict);
      var request = new Mock&lt;HttpRequestBase&gt;(MockBehavior.Strict);
      var response = new Mock&lt;HttpResponseBase&gt;(MockBehavior.Strict);
      var session = new Mock&lt;HttpSessionStateBase&gt;(MockBehavior.Strict);
      var server = new Mock&lt;HttpServerUtilityBase&gt;(MockBehavior.Strict);
      var cookies = new HttpCookieCollection();
      var items = new ListDictionary();
  
      var mockViewEngine = new Mock&lt;IViewEngine&gt;();
  
      Mock&lt;IView&gt; view = new Mock&lt;IView&gt;();
      var viewResult = new ViewEngineResult(new[] { "location1", "location2" });
  
      mockViewEngine
          .Setup(x =&gt; x.FindView(It.IsAny&lt;ControllerContext&gt;(), It.IsAny&lt;string&gt;(), It.IsAny&lt;string&gt;(), It.IsAny&lt;bool&gt;()))
          .Returns(viewResult);
  
      ViewEngines.Engines.Clear();
      ViewEngines.Engines.Add(mockViewEngine.Object);
  
      browser.Setup(b =&gt; b.IsMobileDevice).Returns(false);
      request.Setup(r =&gt; r.Cookies).Returns(cookies);
      request.Setup(r =&gt; r.ValidateInput());
      request.Setup(r =&gt; r.UserAgent).Returns("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11");
      response.Setup(r =&gt; r.Cookies).Returns(cookies);
  
      request.Setup(r =&gt; r.Browser).Returns(browser.Object);
      HttpContextBaseMock.Setup(ctx =&gt; ctx.Items).Returns(items);
  
      var routes = new RouteCollection();
  
      var ControllerContext = new Mock&lt;ControllerContext&gt;(HttpContextBaseMock.Object, _routeData, sut);
  
      var controller = new Mock&lt;PublicPortalController&gt;();
  
      ControllerContext.SetupGet(c =&gt; c.Controller).Returns(controller.Object);
      ControllerContext.SetupGet(c =&gt; c.HttpContext).Returns(HttpContextBaseMock.Object);
  
      sut.Url = new UrlHelper(new RequestContext(HttpContextBaseMock.Object, _routeData), routes);
      sut.ControllerContext = ControllerContext.Object;
      var basecontroller = new Mock&lt;RequestITBaseController&gt;();
  
      var fakePublicPortalViewModel = new Mock&lt;PublicPortalViewModel&gt;();
      fakePublicPortalViewModel.Setup(m =&gt; m.RequestNumber).Returns("23");
      bool captchaValid = true;
  
      basecontroller.Setup(c =&gt; c.SerializeView("DisplayPublicInformation", fakePublicPortalViewModel)).Returns("");
  
      var result = sut.GetPublicInformation(fakePublicPortalViewModel.Object, captchaValid) as JsonResult;
      dynamic jsonObject = result.Data;
  
      Assert.IsTrue(jsonObject.success);
  }
  
  private void SetupRouteData()
  {
      SetupParentRouteData();
      var viewContext = new ViewContext { RouteData = _parentRouteData };
  
      _routeData = new RouteData();
      _routeData.Values.Add("controller", "PublicPortalController");
      _routeData.Values.Add("action", "GetPublicInformation");
      _routeData.DataTokens["ParentActionViewContext"] = viewContext;
  }
  
  private void SetupParentRouteData()
  {
      _parentRouteData = new RouteData();
      _parentRouteData.Values.Add("controller", "PublicPortalController");
      _parentRouteData.Values.Add("action", "Index");
  }
  </code></pre>