Friday, 18 June 2010

Mock ControllerContexts in ASP.Net MVC

After performing an upgrade to MVC 2 for a web application last week, I had a number of tests failing. This gave me an opportunity to refactor some controller tests and create a base class for my controller test classes. This new base class is straight forward and allows me to mock HttpRequestBase and HttpSessionStateBase easily on the mock ControllerContext - it also has an overload for mocking AJAX requests too. I expect this class to grow in time but it serves my needs for now:

public class TestController
{
 public static ControllerContext GetMockControllerContext()
 {
  return GetMockControllerContext("GET", false, null, null);
 }

 public static ControllerContext GetMockControllerContext(string httpMethod, bool isAjaxRequest)
 {
  return GetMockControllerContext(httpMethod, isAjaxRequest, null, null);
 }

 public static ControllerContext GetMockControllerContext(Mock httpRequestBase, Mock httpSessionStateBase)
 {
  return GetMockControllerContext("GET", false, httpRequestBase, httpSessionStateBase);
 }

 public static ControllerContext GetMockControllerContext(string httpMethod, bool isAjaxRequest, Mock httpRequestBase, Mock httpSessionStateBase)
 {
  var headerCollection = new NameValueCollection();

  // Add header value for ajax requests
  if (isAjaxRequest) headerCollection.Add("X-Requested-With", "XMLHttpRequest");

  if (httpRequestBase == null)
  {
   httpRequestBase = new Mock();
   httpRequestBase.Setup(r => r.HttpMethod).Returns(httpMethod);
   httpRequestBase.Setup(r => r.Headers).Returns(headerCollection);
   httpRequestBase.Setup(r => r.Form).Returns(new NameValueCollection());
   httpRequestBase.Setup(r => r.QueryString).Returns(new NameValueCollection());
  }

  if (httpSessionStateBase == null)
  {
   httpSessionStateBase = new Mock();
  }

  var mockHttpContext = new Mock();
  mockHttpContext.Setup(c => c.Request).Returns(httpRequestBase.Object);
  mockHttpContext.SetupGet(c => c.Session).Returns(httpSessionStateBase.Object);

  return new ControllerContext(mockHttpContext.Object, new RouteData(), new Mock().Object);
 }
}

No comments:

Post a Comment